Commit 0c80da45 authored by Björn Richerzhagen's avatar Björn Richerzhagen
Browse files

Removed deprecated `Position`-Interface

parent db566de9
/*
* 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.api.common;
import de.tudarmstadt.maki.simonstrator.api.common.Transmitable;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
/**
* The common interface for positions within PeerfactSim, this hides the
* business logic of a PositionVector in util.position.
*
* You should consider extending PositionVector for your implementations.
*
* @author Bjoern Richerzhagen
* @version 1.0, 05/26/2011
* @deprecated please consider using {@link Location} instead!
*/
@Deprecated
public interface Position extends Transmitable, Cloneable, Location {
/**
* Get the distance of this position compared to any other Position, if they
* have the same number of dimensions and are compatible.
*
* @param position
* @return
*/
public double getDistance(Position position);
/**
* Calculates the angle <b>in rad</b> from the current position to the
* target.
*
* @param target
* @return An angle in rad between -PI and PI, where 0 is "East", or the
* direction of the positive x-Axis
*/
public double getAngle(Position target);
/**
* This method should be consistent with the getDistance and
* getAngle-methods. It returns a Position that has the given distance and
* angle from the current position.
*
* @param distance
* @param angle
* an angle in rad between -PI and PI, where 0 is the direction
* of the positive x-Axis and angles are incremented
* counter-clockwise (mathematical)
* @return
*/
public Position getTarget(double distance, double angle);
/**
* CLone a Position, ensuring there is no information propagation due to
* Java. Consider a clone() as some kind of snapshot of the current state of
* the cloned position. It is very important to call clone() in scenarios
* with moving hosts!
*
* @return
*/
public Position clone();
}
...@@ -19,40 +19,40 @@ ...@@ -19,40 +19,40 @@
*/ */
package de.tud.kom.p2psim.api.network; package de.tud.kom.p2psim.api.network;
import de.tud.kom.p2psim.api.common.Position;
import de.tud.kom.p2psim.api.common.SimHost; import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.network.routing.RoutingAlgorithm; import de.tud.kom.p2psim.api.network.routing.RoutingAlgorithm;
import de.tudarmstadt.maki.simonstrator.api.Message; import de.tudarmstadt.maki.simonstrator.api.Message;
import de.tudarmstadt.maki.simonstrator.api.component.network.Bandwidth; import de.tudarmstadt.maki.simonstrator.api.component.network.Bandwidth;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetID; import de.tudarmstadt.maki.simonstrator.api.component.network.NetID;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetInterface; import de.tudarmstadt.maki.simonstrator.api.component.network.NetInterface;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
/**
* The NetLayer provides a general interface to encapsulate various networking /**
* models. This way, it is possible to use network solutions with different * The NetLayer provides a general interface to encapsulate various networking
* abstraction levels and complexity. For instance, one can choose either * models. This way, it is possible to use network solutions with different
* between a lightweight simple implementation which offers an adequate model * abstraction levels and complexity. For instance, one can choose either
* with minimum demands in resource requirements and a more complex * between a lightweight simple implementation which offers an adequate model
* implementation capable to model fairshare bandwidth allocation of TCP but * with minimum demands in resource requirements and a more complex
* having a lot of CPU consumption. * implementation capable to model fairshare bandwidth allocation of TCP but
* * having a lot of CPU consumption.
* @author Sebastian Kaune *
* @author Konstantin Pussep * @author Sebastian Kaune
* @version 3.0, 11/29/2007 * @author Konstantin Pussep
* * @version 3.0, 11/29/2007
*/ *
*/
public interface NetLayer extends NetInterface { public interface NetLayer extends NetInterface {
/** /**
* *
* @return * @return
*/ */
public SimHost getHost(); public SimHost getHost();
/** /**
* *
* Deliver a message with the given data to the destination using the given * Deliver a message with the given data to the destination using the given
...@@ -68,48 +68,48 @@ public interface NetLayer extends NetInterface { ...@@ -68,48 +68,48 @@ public interface NetLayer extends NetInterface {
* the remote receiver * the remote receiver
* @param protocol * @param protocol
* the used network protocol * the used network protocol
*/ */
public void send(Message msg, NetID receiver, NetProtocol protocol); public void send(Message msg, NetID receiver, NetProtocol protocol);
/** /**
* Returns whether the network layer has connectivity to the physical * Returns whether the network layer has connectivity to the physical
* network. * network.
* *
* @return return true if the network layer has connectivity to the physical * @return return true if the network layer has connectivity to the physical
* network * network
*/ */
public boolean isOnline(); public boolean isOnline();
/** /**
* Returns whether the network layer has connectivity to the physical * Returns whether the network layer has connectivity to the physical
* network. * network.
* *
* @return return true if the network layer does not have connectivity to * @return return true if the network layer does not have connectivity to
* the physical network * the physical network
*/ */
public boolean isOffline(); public boolean isOffline();
/** /**
* Returns the NetID of a NetLayer instance * Returns the NetID of a NetLayer instance
* *
* @return the NetID of a given NetLayer instance * @return the NetID of a given NetLayer instance
*/ */
public NetID getNetID(); public NetID getNetID();
/** /**
* Establishes the connection to the physical network. Further to this, if * Establishes the connection to the physical network. Further to this, if
* installed, the correspondent ConnectivityListener will be informed about * installed, the correspondent ConnectivityListener will be informed about
* the changes in connectivity. * the changes in connectivity.
* *
*/ */
public void goOnline(); public void goOnline();
/** /**
* Releases the connection to the physical network. Further to this, if * Releases the connection to the physical network. Further to this, if
* installed, the correspondent ConnectivityListener will be informed about * installed, the correspondent ConnectivityListener will be informed about
* the changes in connectivity. * the changes in connectivity.
* *
*/ */
public void goOffline(); public void goOffline();
/** /**
...@@ -122,8 +122,8 @@ public interface NetLayer extends NetInterface { ...@@ -122,8 +122,8 @@ public interface NetLayer extends NetInterface {
* which is described by two numbers--its latitude and its longitude. * which is described by two numbers--its latitude and its longitude.
* *
* @return Position the appropriate position * @return Position the appropriate position
*/ */
public Position getNetPosition(); public Location getNetPosition();
/** /**
* Returns the maximum physical bandwidth that is available at the given * Returns the maximum physical bandwidth that is available at the given
...@@ -131,8 +131,8 @@ public interface NetLayer extends NetInterface { ...@@ -131,8 +131,8 @@ public interface NetLayer extends NetInterface {
* and download connections are closed. * and download connections are closed.
* *
* @return * @return
*/ */
public Bandwidth getMaxBandwidth(); public Bandwidth getMaxBandwidth();
/** /**
* Returns the current available download bandwidth of the network layer as * Returns the current available download bandwidth of the network layer as
...@@ -140,25 +140,25 @@ public interface NetLayer extends NetInterface { ...@@ -140,25 +140,25 @@ public interface NetLayer extends NetInterface {
* connections. * connections.
* *
* @return the available download bandwidth * @return the available download bandwidth
*/ */
public Bandwidth getCurrentBandwidth(); public Bandwidth getCurrentBandwidth();
/** /**
* Adds the given NetMessageListener as a handler for incoming NetMsgEvents * Adds the given NetMessageListener as a handler for incoming NetMsgEvents
* triggered by the NetLayer which implements the message passing from the * triggered by the NetLayer which implements the message passing from the
* NetLayer to a layer above. * NetLayer to a layer above.
* *
* @param listener * @param listener
* the listener for network events * the listener for network events
*/ */
public void addNetMsgListener(NetMessageListener listener); public void addNetMsgListener(NetMessageListener listener);
/** /**
* Removes the given NetMessageListener which handles incoming NetMsgEvents * Removes the given NetMessageListener which handles incoming NetMsgEvents
* *
* @param listener * @param listener
* the listener for network events * the listener for network events
*/ */
public void removeNetMsgListener(NetMessageListener listener); public void removeNetMsgListener(NetMessageListener listener);
} }
...@@ -26,6 +26,7 @@ import de.tud.kom.p2psim.api.topology.social.SocialView; ...@@ -26,6 +26,7 @@ import de.tud.kom.p2psim.api.topology.social.SocialView;
import de.tud.kom.p2psim.api.topology.views.TopologyView; import de.tud.kom.p2psim.api.topology.views.TopologyView;
import de.tud.kom.p2psim.api.topology.waypoints.WaypointModel; import de.tud.kom.p2psim.api.topology.waypoints.WaypointModel;
import de.tud.kom.p2psim.impl.topology.PositionVector; import de.tud.kom.p2psim.impl.topology.PositionVector;
import de.tudarmstadt.maki.simonstrator.api.component.GlobalComponent;
/** /**
* We provide a global Topology-Object (ie. this object is only created once in * We provide a global Topology-Object (ie. this object is only created once in
...@@ -36,7 +37,7 @@ import de.tud.kom.p2psim.impl.topology.PositionVector; ...@@ -36,7 +37,7 @@ import de.tud.kom.p2psim.impl.topology.PositionVector;
* @author Bjoern Richerzhagen * @author Bjoern Richerzhagen
* @version 1.0, 21.02.2012 * @version 1.0, 21.02.2012
*/ */
public interface Topology { public interface Topology extends GlobalComponent {
/** /**
* This Position Vector contains the upper bounds for each dimension used in * This Position Vector contains the upper bounds for each dimension used in
......
...@@ -20,9 +20,7 @@ ...@@ -20,9 +20,7 @@
package de.tud.kom.p2psim.api.topology; package de.tud.kom.p2psim.api.topology;
import de.tud.kom.p2psim.api.common.Position;
import de.tud.kom.p2psim.api.common.SimHostComponent; import de.tud.kom.p2psim.api.common.SimHostComponent;
import de.tud.kom.p2psim.api.energy.EnergyComponent;
import de.tud.kom.p2psim.api.topology.movement.MovementListener; import de.tud.kom.p2psim.api.topology.movement.MovementListener;
import de.tud.kom.p2psim.api.topology.movement.MovementSupported; import de.tud.kom.p2psim.api.topology.movement.MovementSupported;
import de.tud.kom.p2psim.api.topology.views.TopologyView; import de.tud.kom.p2psim.api.topology.views.TopologyView;
...@@ -40,33 +38,10 @@ import de.tudarmstadt.maki.simonstrator.api.component.topology.UnderlayTopologyP ...@@ -40,33 +38,10 @@ import de.tudarmstadt.maki.simonstrator.api.component.topology.UnderlayTopologyP
public interface TopologyComponent extends SimHostComponent, MovementSupported, public interface TopologyComponent extends SimHostComponent, MovementSupported,
MovementListener, UnderlayTopologyProvider, LocationSensor { MovementListener, UnderlayTopologyProvider, LocationSensor {
/**
* Abstract QoS-Classes for the Accuracy of the position. Implementation
* depends on the {@link EnergyComponent}
*
* @author Bjoern Richerzhagen
* @version 1.0, 26.02.2012
*/
@Deprecated
public static enum PositionAccuracy {
HIGH, MEDIUM, LOW
}
/**
* This uses an {@link EnergyComponent} for position retrieving (ie a GPS).
* A call might trigger energy consumption and the result will in most cases
* not be 100% accurate. Use this in your application if you want to add
* another layer of realism.
*
* @param accuracy
* a QoS-Class for the accuracy
* @return An estimate of the current position
*/
@Deprecated
public Position getPosition(PositionAccuracy accuracy);
/** /**
* Returns the Topology-Object that provides access to {@link TopologyView}s * Returns the Topology-Object that provides access to {@link TopologyView}s
* Note: the {@link Topology} is also available as a GlobalComponent via the
* Binder-class.
* *
* @return * @return
*/ */
......
...@@ -24,7 +24,6 @@ import java.util.List; ...@@ -24,7 +24,6 @@ import java.util.List;
import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.Geometry;
import de.tud.kom.p2psim.api.common.Position;
import de.tud.kom.p2psim.api.topology.views.TopologyView; import de.tud.kom.p2psim.api.topology.views.TopologyView;
import de.tud.kom.p2psim.impl.topology.PositionVector; import de.tud.kom.p2psim.impl.topology.PositionVector;
......
...@@ -23,13 +23,13 @@ package de.tud.kom.p2psim.api.topology.views; ...@@ -23,13 +23,13 @@ package de.tud.kom.p2psim.api.topology.views;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import de.tud.kom.p2psim.api.common.Position;
import de.tud.kom.p2psim.api.linklayer.mac.Link; import de.tud.kom.p2psim.api.linklayer.mac.Link;
import de.tud.kom.p2psim.api.linklayer.mac.MacAddress; import de.tud.kom.p2psim.api.linklayer.mac.MacAddress;
import de.tud.kom.p2psim.api.linklayer.mac.MacLayer; import de.tud.kom.p2psim.api.linklayer.mac.MacLayer;
import de.tud.kom.p2psim.api.linklayer.mac.PhyType; import de.tud.kom.p2psim.api.linklayer.mac.PhyType;
import de.tud.kom.p2psim.api.topology.TopologyListener; import de.tud.kom.p2psim.api.topology.TopologyListener;
import de.tud.kom.p2psim.api.topology.movement.MovementListener; import de.tud.kom.p2psim.api.topology.movement.MovementListener;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
/** /**
* Each MAC has a view on the global topology of hosts (ie. the * Each MAC has a view on the global topology of hosts (ie. the
...@@ -119,7 +119,7 @@ public interface TopologyView extends TopologyListener, MovementListener { ...@@ -119,7 +119,7 @@ public interface TopologyView extends TopologyListener, MovementListener {
* The {@link MacAddress} of the host * The {@link MacAddress} of the host
* @return The real Position of the Host. * @return The real Position of the Host.
*/ */
public Position getPosition(MacAddress address); public Location getPosition(MacAddress address);
/** /**
* Gets the real distance between the two hosts. * Gets the real distance between the two hosts.
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
package de.tud.kom.p2psim.api.topology.views.wifi.phy; package de.tud.kom.p2psim.api.topology.views.wifi.phy;
import de.tud.kom.p2psim.api.common.Position; import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
/** /**
* This interface is for the calculation of the propagation loss of an * This interface is for the calculation of the propagation loss of an
...@@ -52,8 +52,8 @@ public abstract class PropagationLossModel { ...@@ -52,8 +52,8 @@ public abstract class PropagationLossModel {
* The second position * The second position
* @return The RX power in dBm * @return The RX power in dBm
*/ */
public abstract double getRxPowerDbm(double txPowerDbm, Position a, public abstract double getRxPowerDbm(double txPowerDbm, Location a,
Position b); Location b);
/** /**
* Gets the RX Power in dBm for the distance. * Gets the RX Power in dBm for the distance.
......
...@@ -28,13 +28,13 @@ import java.util.List; ...@@ -28,13 +28,13 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import de.tud.kom.p2psim.api.common.Position;
import de.tud.kom.p2psim.api.linklayer.mac.MacAddress; import de.tud.kom.p2psim.api.linklayer.mac.MacAddress;
import de.tud.kom.p2psim.api.linklayer.mac.MacLayer; import de.tud.kom.p2psim.api.linklayer.mac.MacLayer;
import de.tud.kom.p2psim.api.topology.views.wifi.phy.PropagationLossModel; import de.tud.kom.p2psim.api.topology.views.wifi.phy.PropagationLossModel;
import de.tud.kom.p2psim.api.topology.views.wifi.phy.WifiMode; import de.tud.kom.p2psim.api.topology.views.wifi.phy.WifiMode;
import de.tud.kom.p2psim.api.topology.views.wifi.phy.WifiPhy.Standard_802_11; import de.tud.kom.p2psim.api.topology.views.wifi.phy.WifiPhy.Standard_802_11;
import de.tud.kom.p2psim.impl.topology.views.wifi.phy.InterferenceHelper; import de.tud.kom.p2psim.impl.topology.views.wifi.phy.InterferenceHelper;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
/** /**
* This class is an interface for other implementation of Rate Managers. The * This class is an interface for other implementation of Rate Managers. The
...@@ -598,8 +598,8 @@ public abstract class AbstractRateManager { ...@@ -598,8 +598,8 @@ public abstract class AbstractRateManager {
* antenna. <br> * antenna. <br>
* This is only a helper to calculate the SNR in the AdHocMac. * This is only a helper to calculate the SNR in the AdHocMac.
*/ */
public double calculateActuallySNR(Position startPosition, public double calculateActuallySNR(Location startPosition,
Position targetPosition, WifiMode mode, double txPowerDbm) { Location targetPosition, WifiMode mode, double txPowerDbm) {
InterferenceHelper helper = mac.getWifiTopologyView() InterferenceHelper helper = mac.getWifiTopologyView()
.getInterferenceHelper(); .getInterferenceHelper();
double noiseInterferenceW = helper double noiseInterferenceW = helper
......
...@@ -28,7 +28,6 @@ import java.util.Random; ...@@ -28,7 +28,6 @@ import java.util.Random;
import de.tud.kom.p2psim.api.analyzer.LinklayerAnalyzer; import de.tud.kom.p2psim.api.analyzer.LinklayerAnalyzer;
import de.tud.kom.p2psim.api.analyzer.MessageAnalyzer.Reason; import de.tud.kom.p2psim.api.analyzer.MessageAnalyzer.Reason;
import de.tud.kom.p2psim.api.common.Position;
import de.tud.kom.p2psim.api.common.SimHost; import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.linklayer.LinkLayerMessage; import de.tud.kom.p2psim.api.linklayer.LinkLayerMessage;
import de.tud.kom.p2psim.api.linklayer.mac.Link; import de.tud.kom.p2psim.api.linklayer.mac.Link;
...@@ -47,6 +46,7 @@ import de.tud.kom.p2psim.impl.linklayer.DefaultLinkMessageEvent; ...@@ -47,6 +46,7 @@ import de.tud.kom.p2psim.impl.linklayer.DefaultLinkMessageEvent;
import de.tud.kom.p2psim.impl.linklayer.mac.AbstractMacLayer; import de.tud.kom.p2psim.impl.linklayer.mac.AbstractMacLayer;
import de.tud.kom.p2psim.impl.linklayer.mac.wifi.AbstractRateManager.RateManagerTypes; import de.tud.kom.p2psim.impl.linklayer.mac.wifi.AbstractRateManager.RateManagerTypes;
import de.tud.kom.p2psim.impl.linklayer.mac.wifi.DcfManager.WifiState; import de.tud.kom.p2psim.impl.linklayer.mac.wifi.DcfManager.WifiState;
import de.tud.kom.p2psim.impl.topology.PositionVector;
import de.tud.kom.p2psim.impl.topology.views.wifi.WifiTopologyView; import de.tud.kom.p2psim.impl.topology.views.wifi.WifiTopologyView;
import de.tud.kom.p2psim.impl.util.LiveMonitoring; import de.tud.kom.p2psim.impl.util.LiveMonitoring;
import de.tud.kom.p2psim.impl.util.LiveMonitoring.ProgressValue; import de.tud.kom.p2psim.impl.util.LiveMonitoring.ProgressValue;
...@@ -56,6 +56,7 @@ import de.tudarmstadt.maki.simonstrator.api.Monitor.Level; ...@@ -56,6 +56,7 @@ import de.tudarmstadt.maki.simonstrator.api.Monitor.Level;
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.Time;
import de.tudarmstadt.maki.simonstrator.api.component.core.MonitorComponent.AnalyzerNotAvailableException; import de.tudarmstadt.maki.simonstrator.api.component.core.MonitorComponent.AnalyzerNotAvailableException;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
import de.tudarmstadt.maki.simonstrator.api.operation.AbstractOperation; import de.tudarmstadt.maki.simonstrator.api.operation.AbstractOperation;
/** /**
...@@ -671,14 +672,12 @@ public class Ieee80211AdHocMac extends AbstractMacLayer { ...@@ -671,14 +672,12 @@ public class Ieee80211AdHocMac extends AbstractMacLayer {
/** /**
* Gets a copy of the real position of this host. * Gets a copy of the real position of this host.
* *
* Clone <strong>ONLY</strong> here.
*
* @return The position of this host. * @return The position of this host.
*/ */
private Position getPosition() { private PositionVector getPosition() {
/* return this.getHost().getTopologyComponent().getRealPosition().clone();
* FIXME this leads to serious performance degradations. Do we REALLY
* need a copy?
*/
return this.getHost().getTopologyComponent().getRealPosition(); // .clone();
} }
/** /**
...@@ -919,9 +918,9 @@ public class Ieee80211AdHocMac extends AbstractMacLayer { ...@@ -919,9 +918,9 @@ public class Ieee80211AdHocMac extends AbstractMacLayer {
WifiMacEventInformation eInfo = (WifiMacEventInformation) eventInfo; WifiMacEventInformation eInfo = (WifiMacEventInformation) eventInfo;
// startPosition is from receiver (because ack come from this!) // startPosition is from receiver (because ack come from this!)
Position startPosition = ((Ieee80211AdHocMac) topoView Location startPosition = ((Ieee80211AdHocMac) topoView
.getMac(eventInfo.getReceiver())).getPosition(); .getMac(eventInfo.getReceiver())).getPosition();
Position targetPosition = this.getPosition(); Location targetPosition = this.getPosition();
double ackSnr = rateManager.calculateActuallySNR(startPosition, double ackSnr = rateManager.calculateActuallySNR(startPosition,
targetPosition, eInfo.getAckMode(), txPowerDbm); targetPosition, eInfo.getAckMode(), txPowerDbm);
rateManager.reportDataOk(eventInfo.getReceiver(), ackSnr, rateManager.reportDataOk(eventInfo.getReceiver(), ackSnr,
......
...@@ -26,7 +26,6 @@ import java.util.List; ...@@ -26,7 +26,6 @@ import java.util.List;
import de.tud.kom.p2psim.api.analyzer.ConnectivityAnalyzer; import de.tud.kom.p2psim.api.analyzer.ConnectivityAnalyzer;
import de.tud.kom.p2psim.api.analyzer.MessageAnalyzer.Reason; import de.tud.kom.p2psim.api.analyzer.MessageAnalyzer.Reason;
import de.tud.kom.p2psim.api.analyzer.NetlayerAnalyzer; import de.tud.kom.p2psim.api.analyzer.NetlayerAnalyzer;
import de.tud.kom.p2psim.api.common.Position;
import de.tud.kom.p2psim.api.common.SimHost; import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.linklayer.mac.PhyType; import de.tud.kom.p2psim.api.linklayer.mac.PhyType;
import de.tud.kom.p2psim.api.network.NetMessage; import de.tud.kom.p2psim.api.network.NetMessage;
...@@ -42,6 +41,7 @@ import de.tudarmstadt.maki.simonstrator.api.component.core.MonitorComponent.Anal ...@@ -42,6 +41,7 @@ import de.tudarmstadt.maki.simonstrator.api.component.core.MonitorComponent.Anal
import de.tudarmstadt.maki.simonstrator.api.component.network.Bandwidth; import de.tudarmstadt.maki.simonstrator.api.component.network.Bandwidth;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetID; import de.tudarmstadt.maki.simonstrator.api.component.network.NetID;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetInterface; import de.tudarmstadt.maki.simonstrator.api.component.network.NetInterface;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
import de.tudarmstadt.maki.simonstrator.api.component.transport.ConnectivityListener; import de.tudarmstadt.maki.simonstrator.api.component.transport.ConnectivityListener;
/** /**
...@@ -70,7 +70,7 @@ public abstract class AbstractNetLayer implements SimNetworkComponent, ...@@ -70,7 +70,7 @@ public abstract class AbstractNetLayer implements SimNetworkComponent,
private boolean online; private boolean online;
private Position position; private Location position;
Bandwidth currentBandwidth; Bandwidth currentBandwidth;
...@@ -93,7 +93,7 @@ public abstract class AbstractNetLayer implements SimNetworkComponent, ...@@ -93,7 +93,7 @@ public abstract class AbstractNetLayer implements SimNetworkComponent,
* the NetPosition of the network layer * the NetPosition of the network layer
*/ */
public AbstractNetLayer(SimHost host, NetID netId, Bandwidth maxBandwidth, public AbstractNetLayer(SimHost host, NetID netId, Bandwidth maxBandwidth,
Position position, NetMeasurementDB.Host hostMeta) { Location position, NetMeasurementDB.Host hostMeta) {
this.myID = netId; this.myID = netId;
this.msgListeners = new LinkedList<NetMessageListener>(); this.msgListeners = new LinkedList<NetMessageListener>();
this.connListeners = new LinkedList<ConnectivityListener>(); this.connListeners = new LinkedList<ConnectivityListener>();
...@@ -378,7 +378,7 @@ public abstract class AbstractNetLayer implements SimNetworkComponent, ...@@ -378,7 +378,7 @@ public abstract class AbstractNetLayer implements SimNetworkComponent,
* @see de.tud.kom.p2psim.api.api.network.NetLayer#getNetPosition() * @see de.tud.kom.p2psim.api.api.network.NetLayer#getNetPosition()
*/ */
@Override @Override
public Position getNetPosition() { public Location getNetPosition() {
return this.position; return this.position;
} }
......
package de.tud.kom.p2psim.impl.network.fairshareng; package de.tud.kom.p2psim.impl.network.fairshareng;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import de.tud.kom.p2psim.api.analyzer.MessageAnalyzer.Reason; import de.tud.kom.p2psim.api.analyzer.MessageAnalyzer.Reason;
import de.tud.kom.p2psim.api.common.Position; import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.common.SimHost; import de.tud.kom.p2psim.api.network.BandwidthImpl;
import de.tud.kom.p2psim.api.network.BandwidthImpl; import de.tud.kom.p2psim.api.network.FlowBasedNetlayer;
import de.tud.kom.p2psim.api.network.FlowBasedNetlayer; import de.tud.kom.p2psim.api.network.NetMessage;
import de.tud.kom.p2psim.api.network.NetMessage; import de.tud.kom.p2psim.api.network.NetProtocol;
import de.tud.kom.p2psim.api.network.NetProtocol; import de.tud.kom.p2psim.api.transport.TransProtocol;
import de.tud.kom.p2psim.api.transport.TransProtocol; import de.tud.kom.p2psim.impl.network.AbstractNetLayer;
import de.tud.kom.p2psim.impl.network.AbstractNetLayer; import de.tud.kom.p2psim.impl.network.IPv4Message;
import de.tud.kom.p2psim.impl.network.IPv4Message; import de.tud.kom.p2psim.impl.network.modular.db.NetMeasurementDB;
import de.tud.kom.p2psim.impl.network.modular.db.NetMeasurementDB; import de.tud.kom.p2psim.impl.transport.AbstractTransMessage;
import de.tud.kom.p2psim.impl.transport.AbstractTransMessage; import de.tudarmstadt.maki.simonstrator.api.Message;
import de.tudarmstadt.maki.simonstrator.api.Message; import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.Monitor; import de.tudarmstadt.maki.simonstrator.api.Monitor.Level;
import de.tudarmstadt.maki.simonstrator.api.Monitor.Level; import de.tudarmstadt.maki.simonstrator.api.component.network.NetID;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetID; import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
/** /**
* The Class Node. * The Class Node.
*/ */
public class FairshareNode extends AbstractNetLayer implements public class FairshareNode extends AbstractNetLayer implements
FlowBasedNetlayer { FlowBasedNetlayer {
/** The subnet. */ /** The subnet. */
private final FairshareSubnet subnet; private final FairshareSubnet subnet;
/** The host queues. */ /** The host queues. */
private final Map<FairshareNode, LinkedList<NetMessage>> hostQueues; private final Map<FairshareNode, LinkedList<NetMessage>> hostQueues;
/** The Constant FLOAT_DELTA to correct Floats 9.999 to 10. */ /** The Constant FLOAT_DELTA to correct Floats 9.999 to 10. */
private final static float FLOAT_DELTA = 1e-7f; private final static float FLOAT_DELTA = 1e-7f;
/** The hash code. */ /** The hash code. */
private final int hashCode; private final int hashCode;
/** /**
* Instantiates a new node. * Instantiates a new node.
* @param netID * @param netID
* @param geoLoc * @param geoLoc
*/ */
public FairshareNode(SimHost host, FairshareSubnet subnet, NetID netID, public FairshareNode(SimHost host, FairshareSubnet subnet, NetID netID,
BandwidthImpl maxBandwidth, Position position, BandwidthImpl maxBandwidth, Location position,
NetMeasurementDB.Host hostMeta) { NetMeasurementDB.Host hostMeta) {
super(host, netID, maxBandwidth, position, hostMeta); super(host, netID, maxBandwidth, position, hostMeta);
this.subnet = subnet; this.subnet = subnet;
this.hostQueues = new LinkedHashMap<FairshareNode, LinkedList<NetMessage>>(); this.hostQueues = new LinkedHashMap<FairshareNode, LinkedList<NetMessage>>();
this.hashCode = this.getNetID().hashCode(); this.hashCode = this.getNetID().hashCode();
} }
/** /**
* Adds rate to the current down rate. * Adds rate to the current down rate.
* *
* @param downRate * @param downRate
* *
* the down rate * the down rate
* @throws Exception * @throws Exception
* the exception * the exception
*/ */
public void addCurrentDownRate(double downRate) throws Exception { public void addCurrentDownRate(double downRate) throws Exception {
final double currentDownBW = this.getCurrentBandwidth().getDownBW(); final double currentDownBW = this.getCurrentBandwidth().getDownBW();
double realDownRate = currentDownBW - downRate; double realDownRate = currentDownBW - downRate;
/* Fix float, in case we get 9.999 save 10. */ /* Fix float, in case we get 9.999 save 10. */
if( Math.abs(Math.round(realDownRate) - realDownRate) < FLOAT_DELTA ) { if( Math.abs(Math.round(realDownRate) - realDownRate) < FLOAT_DELTA ) {
realDownRate = Math.round(realDownRate); realDownRate = Math.round(realDownRate);
} }
this.getCurrentBandwidth().setDownBW(realDownRate); this.getCurrentBandwidth().setDownBW(realDownRate);
} }
/** /**
* Adds rate to the current up rate. * Adds rate to the current up rate.
* *
* @param upRate * @param upRate
* the up rate * the up rate
* @throws Exception * @throws Exception
* the exception * the exception
*/ */
public void addCurrentUpRate(double upRate) throws Exception { public void addCurrentUpRate(double upRate) throws Exception {
final double currentUpBW = this.getCurrentBandwidth().getUpBW(); final double currentUpBW = this.getCurrentBandwidth().getUpBW();
double realUpRate = currentUpBW - upRate; double realUpRate = currentUpBW - upRate;
/* Fix float, in case we get 9.999 save 10. */ /* Fix float, in case we get 9.999 save 10. */
if( Math.abs(Math.round(realUpRate) - realUpRate) < FLOAT_DELTA ) { if( Math.abs(Math.round(realUpRate) - realUpRate) < FLOAT_DELTA ) {
realUpRate = Math.round(realUpRate); realUpRate = Math.round(realUpRate);
} }
this.getCurrentBandwidth().setUpBW(realUpRate); this.getCurrentBandwidth().setUpBW(realUpRate);
} }
/** /**
* Resets the node by setting current rates to zero. * Resets the node by setting current rates to zero.
*/ */
public void reset() { public void reset() {
this.setCurrentBandwidth(this.getMaxBandwidth().clone()); this.setCurrentBandwidth(this.getMaxBandwidth().clone());
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see de.tud.kom.p2psim.impl.network.AbstractNetLayer#goOffline() * @see de.tud.kom.p2psim.impl.network.AbstractNetLayer#goOffline()
*/ */
@Override @Override
public void goOffline() { public void goOffline() {
super.goOffline(); super.goOffline();
this.subnet.disconnectHost(this); this.subnet.disconnectHost(this);
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see de.tud.kom.p2psim.api.network.NetLayer#send(de.tud.kom.p2psim.api.common.Message, de.tud.kom.p2psim.api.network.NetID, de.tud.kom.p2psim.api.network.NetProtocol) * @see de.tud.kom.p2psim.api.network.NetLayer#send(de.tud.kom.p2psim.api.common.Message, de.tud.kom.p2psim.api.network.NetID, de.tud.kom.p2psim.api.network.NetProtocol)
*/ */
@Override @Override
public void send(Message msg, NetID receiverId, NetProtocol protocol) { public void send(Message msg, NetID receiverId, NetProtocol protocol) {
if (isOnline()) { if (isOnline()) {
assert (msg.getSize() >= 0); assert (msg.getSize() >= 0);
assert (isSupported(((AbstractTransMessage) msg).getProtocol())); assert (isSupported(((AbstractTransMessage) msg).getProtocol()));
final NetMessage netMsg = new IPv4Message(msg, receiverId, this.getNetID()); final NetMessage netMsg = new IPv4Message(msg, receiverId, this.getNetID());
final TransProtocol tpMsg = ((AbstractTransMessage) msg).getProtocol(); final TransProtocol tpMsg = ((AbstractTransMessage) msg).getProtocol();
if (tpMsg.equals(TransProtocol.UDP)) { if (tpMsg.equals(TransProtocol.UDP)) {
if (hasAnalyzer) { if (hasAnalyzer) {
netAnalyzerProxy netAnalyzerProxy
.netMsgEvent(netMsg, getHost(), Reason.SEND); .netMsgEvent(netMsg, getHost(), Reason.SEND);
} }
this.subnet.sendUDP(netMsg); this.subnet.sendUDP(netMsg);
} else if (tpMsg.equals(TransProtocol.TCP)) { } else if (tpMsg.equals(TransProtocol.TCP)) {
final FairshareNode receiver = this.subnet.getNetLayer(receiverId); final FairshareNode receiver = this.subnet.getNetLayer(receiverId);
LinkedList<NetMessage> queuedMessages = this.hostQueues.get(receiver); LinkedList<NetMessage> queuedMessages = this.hostQueues.get(receiver);
if (queuedMessages == null) { if (queuedMessages == null) {
queuedMessages = new LinkedList<NetMessage>(); queuedMessages = new LinkedList<NetMessage>();
this.hostQueues.put(receiver, queuedMessages); this.hostQueues.put(receiver, queuedMessages);
} }
if (hasAnalyzer) { if (hasAnalyzer) {
netAnalyzerProxy netAnalyzerProxy
.netMsgEvent(netMsg, getHost(), Reason.SEND); .netMsgEvent(netMsg, getHost(), Reason.SEND);
} }
if (queuedMessages.isEmpty()) { if (queuedMessages.isEmpty()) {
try { try {
this.subnet.sendTCPMessage(netMsg); this.subnet.sendTCPMessage(netMsg);
} catch (final Exception e) { } catch (final Exception e) {
/* /*
* Can't throw exception here as send(Message msg, NetID receiverId, NetProtocol protocol) is overwritten. * Can't throw exception here as send(Message msg, NetID receiverId, NetProtocol protocol) is overwritten.
*/ */
Monitor.log(FairshareNode.class, Level.ERROR, Monitor.log(FairshareNode.class, Level.ERROR,
"Exception..: sendTCP failed. %s", e); "Exception..: sendTCP failed. %s", e);
assert(false) : "sendTCP failed: " + e; assert(false) : "sendTCP failed: " + e;
} }
} }
queuedMessages.add(netMsg); queuedMessages.add(netMsg);
} else { } else {
/* /*
* Can't throw exception here as send(Message msg, NetID receiverId, NetProtocol protocol) is overwritten. * Can't throw exception here as send(Message msg, NetID receiverId, NetProtocol protocol) is overwritten.
*/ */
Monitor.log(FairshareNode.class, Level.ERROR, Monitor.log(FairshareNode.class, Level.ERROR,
"Unsupported transport protocol " + tpMsg); "Unsupported transport protocol " + tpMsg);
assert (false) : "Unsupported transport protocol " + tpMsg; assert (false) : "Unsupported transport protocol " + tpMsg;
} }
} else { } else {
Monitor.log(FairshareNode.class, Level.WARN, "Host " + this Monitor.log(FairshareNode.class, Level.WARN, "Host " + this
+ " is offline."); + " is offline.");
} }
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see de.tud.kom.p2psim.impl.network.AbstractNetLayer#isSupported(de.tud.kom.p2psim.api.transport.TransProtocol) * @see de.tud.kom.p2psim.impl.network.AbstractNetLayer#isSupported(de.tud.kom.p2psim.api.transport.TransProtocol)
*/ */
@Override @Override
protected boolean isSupported(TransProtocol protocol) { protected boolean isSupported(TransProtocol protocol) {
return (protocol.equals(TransProtocol.UDP) || protocol.equals(TransProtocol.TCP)); return (protocol.equals(TransProtocol.UDP) || protocol.equals(TransProtocol.TCP));
} }
/** /**
* Checks if message queue is empty. * Checks if message queue is empty.
* *
* @param receiver the receiver * @param receiver the receiver
* @return true, if is message queue empty * @return true, if is message queue empty
*/ */
public boolean isMessageQueueEmpty(FairshareNode receiver) { public boolean isMessageQueueEmpty(FairshareNode receiver) {
return this.hostQueues.get(receiver).isEmpty(); return this.hostQueues.get(receiver).isEmpty();
} }
/** /**
* Peek message queue and return size of next expected arrival. * Peek message queue and return size of next expected arrival.
* *
* @param receiver the receiver * @param receiver the receiver
* @return the double * @return the double
*/ */
public double peekMessageQueue(FairshareNode receiver) { public double peekMessageQueue(FairshareNode receiver) {
return this.hostQueues.get(receiver).get(0).getSize(); return this.hostQueues.get(receiver).get(0).getSize();
} }
/** /**
* Gets a read-only view on message queue. * Gets a read-only view on message queue.
* *
* @param receiver the receiver * @param receiver the receiver
* @return the view on message queue * @return the view on message queue
*/ */
public List<NetMessage> getViewOnMessageQueue(FairshareNode receiver) { public List<NetMessage> getViewOnMessageQueue(FairshareNode receiver) {
return Collections.unmodifiableList(this.hostQueues.get(receiver)); return Collections.unmodifiableList(this.hostQueues.get(receiver));
} }
/** /**
* Removes the message from queue. * Removes the message from queue.
* *
* @param receiver the receiver * @param receiver the receiver
* @return the net message * @return the net message
*/ */
public NetMessage removeMessageFromQueue(FairshareNode receiver) { public NetMessage removeMessageFromQueue(FairshareNode receiver) {
return this.hostQueues.get(receiver).remove(0); return this.hostQueues.get(receiver).remove(0);
} }
/* /*
* (non-Javadoc) * (non-Javadoc)
* *
* @see java.lang.Object#equals(java.lang.Object) * @see java.lang.Object#equals(java.lang.Object)
*/ */
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
return (obj instanceof FairshareNode) ? ((FairshareNode) obj).getNetID().hashCode() == this.getNetID().hashCode() : super.equals(obj); return (obj instanceof FairshareNode) ? ((FairshareNode) obj).getNetID().hashCode() == this.getNetID().hashCode() : super.equals(obj);
} }
/* /*
* (non-Javadoc) * (non-Javadoc)
* *
* @see java.lang.Object#toString() * @see java.lang.Object#toString()
*/ */
@Override @Override
public String toString() { public String toString() {
return this.getLocalInetAddress() + " (U:" return this.getLocalInetAddress() + " (U:"
+ this.getCurrentBandwidth().getUpBW() + "/D:" + this.getCurrentBandwidth().getUpBW() + "/D:"
+ this.getCurrentBandwidth().getDownBW() + ")"; + this.getCurrentBandwidth().getDownBW() + ")";
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see java.lang.Object#hashCode() * @see java.lang.Object#hashCode()
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
/* Precomputed to save time. */ /* Precomputed to save time. */
return this.hashCode; return this.hashCode;
} }
} }
...@@ -19,12 +19,10 @@ ...@@ -19,12 +19,10 @@
*/ */
package de.tud.kom.p2psim.impl.network.gnp; package de.tud.kom.p2psim.impl.network.gnp;
import java.util.Random; import java.util.Random;
import umontreal.iro.lecuyer.probdist.LognormalDist;
import de.tud.kom.p2psim.api.common.Position;
import de.tud.kom.p2psim.api.linklayer.mac.PhyType; import de.tud.kom.p2psim.api.linklayer.mac.PhyType;
import de.tud.kom.p2psim.api.network.NetLatencyModel; import de.tud.kom.p2psim.api.network.NetLatencyModel;
import de.tud.kom.p2psim.api.network.NetLayer; import de.tud.kom.p2psim.api.network.NetLayer;
...@@ -35,133 +33,135 @@ import de.tud.kom.p2psim.impl.network.gnp.topology.CountryLookup; ...@@ -35,133 +33,135 @@ import de.tud.kom.p2psim.impl.network.gnp.topology.CountryLookup;
import de.tud.kom.p2psim.impl.network.gnp.topology.PingErLookup; import de.tud.kom.p2psim.impl.network.gnp.topology.PingErLookup;
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.Time;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
import umontreal.iro.lecuyer.probdist.LognormalDist;
public class GnpLatencyModel implements NetLatencyModel { public class GnpLatencyModel implements NetLatencyModel {
private Random rnd = Randoms.getRandom(GnpLatencyModel.class); private Random rnd = Randoms.getRandom(GnpLatencyModel.class);
public static final int MSS = PhyType.ETHERNET.getDefaultMTU() public static final int MSS = PhyType.ETHERNET.getDefaultMTU()
- NetProtocol.IPv4.getHeaderSize() - NetProtocol.IPv4.getHeaderSize()
- TransProtocol.TCP.getHeaderSize(); - TransProtocol.TCP.getHeaderSize();
private static PingErLookup pingErLookup; private static PingErLookup pingErLookup;
private static CountryLookup countryLookup; private static CountryLookup countryLookup;
private boolean usePingErInsteadOfGnp = false; private boolean usePingErInsteadOfGnp = false;
private boolean useAnalyticalFunctionInsteadOfGnp = false; private boolean useAnalyticalFunctionInsteadOfGnp = false;
private boolean usePingErJitter = false; private boolean usePingErJitter = false;
private boolean usePingErPacketLoss = false; private boolean usePingErPacketLoss = false;
public void init(PingErLookup pingErLookup, CountryLookup countryLookup) { public void init(PingErLookup pingErLookup, CountryLookup countryLookup) {
GnpLatencyModel.pingErLookup = pingErLookup; GnpLatencyModel.pingErLookup = pingErLookup;
GnpLatencyModel.countryLookup = countryLookup; GnpLatencyModel.countryLookup = countryLookup;
} }
private double getMinimumRTT(GnpNetLayer sender, GnpNetLayer receiver) { private double getMinimumRTT(GnpNetLayer sender, GnpNetLayer receiver) {
String ccSender = sender.getCountryCode(); String ccSender = sender.getCountryCode();
String ccReceiver = receiver.getCountryCode(); String ccReceiver = receiver.getCountryCode();
double minRtt = 0.0; double minRtt = 0.0;
if (usePingErInsteadOfGnp) { if (usePingErInsteadOfGnp) {
minRtt = pingErLookup.getMinimumRtt(ccSender, ccReceiver, countryLookup); minRtt = pingErLookup.getMinimumRtt(ccSender, ccReceiver, countryLookup);
} else if (useAnalyticalFunctionInsteadOfGnp) { } else if (useAnalyticalFunctionInsteadOfGnp) {
double distance = GeoLocationOracle.getGeographicalDistance(sender.getNetID(), receiver.getNetID()); double distance = GeoLocationOracle.getGeographicalDistance(sender.getNetID(), receiver.getNetID());
minRtt = 62 + (0.02 * distance); minRtt = 62 + (0.02 * distance);
} else { } else {
Position senderPos = sender.getNetPosition(); Location senderPos = sender.getNetPosition();
Position receiverPos = receiver.getNetPosition(); Location receiverPos = receiver.getNetPosition();
minRtt = senderPos.getDistance(receiverPos); minRtt = senderPos.distanceTo(receiverPos);
} }
return minRtt; return minRtt;
} }
private double getPacketLossProbability(GnpNetLayer sender, GnpNetLayer receiver) { private double getPacketLossProbability(GnpNetLayer sender, GnpNetLayer receiver) {
String ccSender = sender.getCountryCode(); String ccSender = sender.getCountryCode();
String ccReceiver = receiver.getCountryCode(); String ccReceiver = receiver.getCountryCode();
double twoWayLossRate = 0.0; double twoWayLossRate = 0.0;
double oneWayLossRate = 0.0; double oneWayLossRate = 0.0;
if (usePingErPacketLoss) { if (usePingErPacketLoss) {
twoWayLossRate = pingErLookup.getPacktLossRate(ccSender, ccReceiver, countryLookup); twoWayLossRate = pingErLookup.getPacktLossRate(ccSender, ccReceiver, countryLookup);
twoWayLossRate /= 100; twoWayLossRate /= 100;
oneWayLossRate = 1 - Math.sqrt(1 - twoWayLossRate); oneWayLossRate = 1 - Math.sqrt(1 - twoWayLossRate);
} }
return oneWayLossRate; return oneWayLossRate;
} }
private double getNextJitter(GnpNetLayer sender, GnpNetLayer receiver) { private double getNextJitter(GnpNetLayer sender, GnpNetLayer receiver) {
String ccSender = sender.getCountryCode(); String ccSender = sender.getCountryCode();
String ccReceiver = receiver.getCountryCode(); String ccReceiver = receiver.getCountryCode();
double randomJitter = 0.0; double randomJitter = 0.0;
if (usePingErJitter) { if (usePingErJitter) {
LognormalDist distri = pingErLookup.getJitterDistribution(ccSender, ccReceiver, countryLookup); LognormalDist distri = pingErLookup.getJitterDistribution(ccSender, ccReceiver, countryLookup);
randomJitter = distri.inverseF(rnd.nextDouble()); randomJitter = distri.inverseF(rnd.nextDouble());
} }
return randomJitter; return randomJitter;
} }
private double getAverageJitter(GnpNetLayer sender, GnpNetLayer receiver) { private double getAverageJitter(GnpNetLayer sender, GnpNetLayer receiver) {
String ccSender = sender.getCountryCode(); String ccSender = sender.getCountryCode();
String ccReceiver = receiver.getCountryCode(); String ccReceiver = receiver.getCountryCode();
double jitter = 0.0; double jitter = 0.0;
if (usePingErJitter) { if (usePingErJitter) {
jitter = pingErLookup.getAverageRtt(ccSender, ccReceiver, countryLookup) - pingErLookup.getMinimumRtt(ccSender, ccReceiver, countryLookup); jitter = pingErLookup.getAverageRtt(ccSender, ccReceiver, countryLookup) - pingErLookup.getMinimumRtt(ccSender, ccReceiver, countryLookup);
} }
return jitter; return jitter;
} }
public double getUDPerrorProbability(GnpNetLayer sender, GnpNetLayer receiver, IPv4Message msg) { public double getUDPerrorProbability(GnpNetLayer sender, GnpNetLayer receiver, IPv4Message msg) {
if (msg.getPayload().getSize() > 65507) if (msg.getPayload().getSize() > 65507)
throw new IllegalArgumentException("Message-Size ist too big for a UDP-Datagramm (max 65507 byte)"); throw new IllegalArgumentException("Message-Size ist too big for a UDP-Datagramm (max 65507 byte)");
double lp = getPacketLossProbability(sender, receiver); double lp = getPacketLossProbability(sender, receiver);
double errorProb = 1 - Math.pow(1 - lp, msg.getNoOfFragments()); double errorProb = 1 - Math.pow(1 - lp, msg.getNoOfFragments());
return errorProb; return errorProb;
} }
public double getTcpThroughput(GnpNetLayer sender, GnpNetLayer receiver) { public double getTcpThroughput(GnpNetLayer sender, GnpNetLayer receiver) {
double minRtt = getMinimumRTT(sender, receiver); double minRtt = getMinimumRTT(sender, receiver);
double averageJitter = getAverageJitter(sender, receiver); double averageJitter = getAverageJitter(sender, receiver);
double packetLossRate = getPacketLossProbability(sender, receiver); double packetLossRate = getPacketLossProbability(sender, receiver);
double mathisBW = ((MSS * 1000) / (minRtt + averageJitter)) * Math.sqrt(1.5 / packetLossRate); double mathisBW = ((MSS * 1000) / (minRtt + averageJitter)) * Math.sqrt(1.5 / packetLossRate);
return mathisBW; return mathisBW;
} }
public long getTransmissionDelay(double bytes, double bandwidth) { public long getTransmissionDelay(double bytes, double bandwidth) {
double messageTime = bytes / bandwidth; double messageTime = bytes / bandwidth;
long delay = Math.round((messageTime * Time.SECOND)); long delay = Math.round((messageTime * Time.SECOND));
return delay; return delay;
} }
public long getPropagationDelay(GnpNetLayer sender, GnpNetLayer receiver) { public long getPropagationDelay(GnpNetLayer sender, GnpNetLayer receiver) {
double minRtt = getMinimumRTT(sender, receiver); double minRtt = getMinimumRTT(sender, receiver);
double randomJitter = getNextJitter(sender, receiver); double randomJitter = getNextJitter(sender, receiver);
double receiveTime = (minRtt + randomJitter) / 2.0; double receiveTime = (minRtt + randomJitter) / 2.0;
long latency = Math.round(receiveTime * Time.MILLISECOND); long latency = Math.round(receiveTime * Time.MILLISECOND);
return latency; return latency;
} }
public long getLatency(NetLayer sender, NetLayer receiver) { public long getLatency(NetLayer sender, NetLayer receiver) {
return getPropagationDelay((GnpNetLayer) sender, (GnpNetLayer) receiver); return getPropagationDelay((GnpNetLayer) sender, (GnpNetLayer) receiver);
} }
public void setUsePingErRttData(boolean pingErRtt) { public void setUsePingErRttData(boolean pingErRtt) {
usePingErInsteadOfGnp = pingErRtt; usePingErInsteadOfGnp = pingErRtt;
} }
public void setUseAnalyticalRtt(boolean analyticalRtt) { public void setUseAnalyticalRtt(boolean analyticalRtt) {
useAnalyticalFunctionInsteadOfGnp = analyticalRtt; useAnalyticalFunctionInsteadOfGnp = analyticalRtt;
} }
public void setUsePingErJitter(boolean pingErRtt) { public void setUsePingErJitter(boolean pingErRtt) {
usePingErJitter = pingErRtt; usePingErJitter = pingErRtt;
} }
public void setUsePingErPacketLoss(boolean pingErPacketLoss) { public void setUsePingErPacketLoss(boolean pingErPacketLoss) {
usePingErPacketLoss = pingErPacketLoss; usePingErPacketLoss = pingErPacketLoss;
} }
} }
\ No newline at end of file
...@@ -19,59 +19,53 @@ ...@@ -19,59 +19,53 @@
*/ */
package de.tud.kom.p2psim.impl.network.gnp.topology; package de.tud.kom.p2psim.impl.network.gnp.topology;
import de.tud.kom.p2psim.api.common.Position;
import de.tud.kom.p2psim.impl.topology.PositionVector; import de.tud.kom.p2psim.impl.topology.PositionVector;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
/**
* Implementation of NetPosition for Position and distance measurnment on the /**
* earth. * Implementation of NetPosition for Position and distance measurnment on the
* * earth.
* @author Gerald Klunker *
* @version 0.1, 05.02.2008 * @author Gerald Klunker
* * @version 0.1, 05.02.2008
*/ *
*/
public class GeographicPosition extends PositionVector {
public class GeographicPosition extends PositionVector {
private double latitude;
private double latitude;
private double longitude;
private double longitude;
/**
* /**
* @param longitude *
* @param latitude * @param longitude
*/ * @param latitude
*/
public GeographicPosition(double longitude, double latitude) { public GeographicPosition(double longitude, double latitude) {
super(new double[] { longitude, latitude }); super(new double[] { longitude, latitude });
this.longitude = longitude; this.longitude = longitude;
this.latitude = latitude; this.latitude = latitude;
}
/**
* @return geographical distance in km
*/
public double getDistance(Position point) {
double pi = 3.14159265;
double radConverter = pi / 180;
double lat1 = latitude * radConverter;
double lat2 = ((GeographicPosition) point).getLatitude() * radConverter;
double delta_lat = lat2 - lat1;
double delta_lon = (((GeographicPosition) point).getLongitude() - longitude)
* radConverter;
double temp = Math.pow(Math.sin(delta_lat / 2), 2) + Math.cos(lat1)
* Math.cos(lat2) * Math.pow(Math.sin(delta_lon / 2), 2);
return 2 * 6378.2 * Math.atan2(Math.sqrt(temp), Math.sqrt(1 - temp));
} }
@Override /**
public double getAngle(Position target) { * @return geographical distance in km
throw new AssertionError( */
"getAngle is not defined for this Position-Type"); public double distanceTo(Location point) {
double pi = 3.14159265;
double radConverter = pi / 180;
double lat1 = latitude * radConverter;
double lat2 = ((GeographicPosition) point).getLatitude() * radConverter;
double delta_lat = lat2 - lat1;
double delta_lon = (((GeographicPosition) point).getLongitude() - longitude)
* radConverter;
double temp = Math.pow(Math.sin(delta_lat / 2), 2) + Math.cos(lat1)
* Math.cos(lat2) * Math.pow(Math.sin(delta_lon / 2), 2);
return 2 * 6378.2 * Math.atan2(Math.sqrt(temp), Math.sqrt(1 - temp));
} }
@Override @Override
...@@ -81,22 +75,22 @@ public class GeographicPosition extends PositionVector { ...@@ -81,22 +75,22 @@ public class GeographicPosition extends PositionVector {
public GeographicPosition clone() { public GeographicPosition clone() {
return new GeographicPosition(longitude, latitude); return new GeographicPosition(longitude, latitude);
} }
/** /**
* *
* @return latitude of position * @return latitude of position
*/ */
public double getLatitude() { public double getLatitude() {
return latitude; return latitude;
} }
/** /**
* *
* @return longitude of position * @return longitude of position
*/ */
public double getLongitude() { public double getLongitude() {
return longitude; return longitude;
} }
} }
...@@ -19,296 +19,283 @@ ...@@ -19,296 +19,283 @@
*/ */
package de.tud.kom.p2psim.impl.network.gnp.topology; package de.tud.kom.p2psim.impl.network.gnp.topology;
import java.util.ArrayList; import java.util.ArrayList;
import de.tud.kom.p2psim.api.common.Position;
import de.tudarmstadt.maki.simonstrator.api.Randoms; import de.tudarmstadt.maki.simonstrator.api.Randoms;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location; import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
/**
* This class implements a NetPosition for a GNP-Based calculation of round trip
* times. Therefore it includes methods for error estimation and methods for
* positioning by a downhill simplex algorithm in the GnpSpace class
*
* @author Gerald Klunker
* @version 0.1, 09.01.2008
*
*/
public class GnpPosition implements Position, Comparable<GnpPosition> { /**
* This class implements a NetPosition for a GNP-Based calculation of round trip
private static final long serialVersionUID = -1103996725403557900L; * times. Therefore it includes methods for error estimation and methods for
* positioning by a downhill simplex algorithm in the GnpSpace class
private double[] gnpCoordinates; *
* @author Gerald Klunker
private GnpSpace gnpRef; * @version 0.1, 09.01.2008
*
private Host hostRef; */
private double error = -1.0; public class GnpPosition implements Location, Comparable<GnpPosition> {
/** private static final long serialVersionUID = -1103996725403557900L;
*
* @param gnpCoordinates private double[] gnpCoordinates;
* coordinate array for new position
*/ private GnpSpace gnpRef;
public GnpPosition(double[] gnpCoordinates) {
super(); private Host hostRef;
this.gnpCoordinates = gnpCoordinates;
} private double error = -1.0;
/** /**
* Object will be initialized with a random position. Position must be *
* random according to the downhill simplex * @param gnpCoordinates
* * coordinate array for new position
* @param noOfDimensions */
* number of dimensions public GnpPosition(double[] gnpCoordinates) {
* @param hostRef super();
* related Host object this.gnpCoordinates = gnpCoordinates;
* @param gnpRef }
* related GnpSpace object
*/ /**
public GnpPosition(int noOfDimensions, Host hostRef, GnpSpace gnpRef) { * Object will be initialized with a random position. Position must be
super(); * random according to the downhill simplex
gnpCoordinates = new double[noOfDimensions]; *
this.hostRef = hostRef; * @param noOfDimensions
this.gnpRef = gnpRef; * number of dimensions
for (int c = 0; c < gnpCoordinates.length; c++) * @param hostRef
* related Host object
* @param gnpRef
* related GnpSpace object
*/
public GnpPosition(int noOfDimensions, Host hostRef, GnpSpace gnpRef) {
super();
gnpCoordinates = new double[noOfDimensions];
this.hostRef = hostRef;
this.gnpRef = gnpRef;
for (int c = 0; c < gnpCoordinates.length; c++)
gnpCoordinates[c] = Randoms.getRandom(GnpPosition.class) gnpCoordinates[c] = Randoms.getRandom(GnpPosition.class)
.nextDouble(); .nextDouble();
}
/**
*
* @param dimension
* @param maxDiversity
*/
public void diversify(double[][] dimension, double maxDiversity) {
for (int c = 0; c < this.gnpCoordinates.length; c++) {
double rand = (2 * maxDiversity * Math.random()) - maxDiversity;
gnpCoordinates[c] = gnpCoordinates[c] + (rand * dimension[c][2]);
}
error = -1.0;
}
/**
* reposition
*
* @param pos
* position in the coordinate array
* @param value
* new value at position pos
*/
public void setGnpCoordinates(int pos, double value) {
gnpCoordinates[pos] = value;
error = -1.0;
}
/**
*
* @return the related GnpSpace object
*/
private GnpSpace getGnpRef() {
return gnpRef;
}
/**
*
* @return the related Host object
*/
public Host getHostRef() {
return hostRef;
}
/**
*
* @return number of dimensions
*/
public int getNoOfDimensions() {
return gnpCoordinates.length;
}
/**
*
* @param pos
* position in the coordinate array
* @return value at position pos
*/
public double getGnpCoordinates(int pos) {
return gnpCoordinates[pos];
}
/**
* Calculates the sum of all errors according to the downhill simplex
* operator.
*
* @return error
*/
public double getDownhillSimplexError() {
if (error < 0.0) {
error = 0.0;
for (int c = 0; c < getGnpRef().getNumberOfMonitors(); c++) {
error += getDownhillSimplexError(getGnpRef()
.getMonitorPosition(c));
}
}
return error;
}
/**
* Calculates the error to a monitor according to the downhill simplex
* operator
*
* @param monitor
* @return error
*/
public double getDownhillSimplexError(GnpPosition monitor) {
double calculatedDistance = this.getDistance(monitor);
double measuredDistance = this.getMeasuredRtt(monitor);
if (Double.compare(measuredDistance, Double.NaN) == 0)
return 0.0;
double error = Math.pow((calculatedDistance - measuredDistance)
/ calculatedDistance, 2);
return error;
}
/**
* Calculates an error, that indicates the deviation of the measured vs. the
* calculated rtt.
*
* @param monitor
* @return error value
*/
public double getDirectionalRelativError(GnpPosition monitor) {
double calculatedDistance = this.getDistance(monitor);
double measuredDistance = this.getMeasuredRtt(monitor);
if (Double.compare(measuredDistance, Double.NaN) == 0)
return Double.NaN;
double error = (calculatedDistance - measuredDistance)
/ Math.min(calculatedDistance, measuredDistance);
return error;
}
/**
* Method must be overwrite to sort different GnpPositions in order of their
* quality.
*
* Is needed for the positioning with the downhill simplex
*
*/
public int compareTo(GnpPosition arg0) {
double val1 = this.getDownhillSimplexError();
double val2 = arg0.getDownhillSimplexError();
if (val1 < val2)
return -1;
if (val1 > val2)
return 1;
else
return 0;
}
/**
*
* @return Comma-separated list of coordinates
*/
public String getCoordinateString() {
if (gnpCoordinates.length == 0) {
return "";
} else {
String result = String.valueOf(gnpCoordinates[0]);
for (int c = 1; c < gnpCoordinates.length; c++)
result = result + "," + gnpCoordinates[c];
return result;
}
}
/**
*
* @param monitor
* @return measured rtt to monitor, nan if no rtt was measured
*/
public double getMeasuredRtt(GnpPosition monitor) {
return this.getHostRef().getRtt(monitor.getHostRef());
}
/**
* @return euclidean distance
*/
public double getDistance(Position point) {
GnpPosition coord = (GnpPosition) point;
double distance = 0.0;
for (int c = 0; c < gnpCoordinates.length; c++)
distance += Math.pow(
gnpCoordinates[c] - coord.getGnpCoordinates(c), 2);
return Math.sqrt(distance);
} }
@Override /**
public double getAngle(Position target) { *
throw new AssertionError( * @param dimension
"getAngle is not defined for this Position-Type"); * @param maxDiversity
*/
public void diversify(double[][] dimension, double maxDiversity) {
for (int c = 0; c < this.gnpCoordinates.length; c++) {
double rand = (2 * maxDiversity * Math.random()) - maxDiversity;
gnpCoordinates[c] = gnpCoordinates[c] + (rand * dimension[c][2]);
}
error = -1.0;
} }
@Override /**
public Position getTarget(double distance, double angle) { * reposition
throw new AssertionError( *
"getTarget is not defined for this Position-Type"); * @param pos
} * position in the coordinate array
* @param value
* new value at position pos
*/
public void setGnpCoordinates(int pos, double value) {
gnpCoordinates[pos] = value;
error = -1.0;
}
/**
*
* @return the related GnpSpace object
*/
private GnpSpace getGnpRef() {
return gnpRef;
}
/**
*
* @return the related Host object
*/
public Host getHostRef() {
return hostRef;
}
/**
*
* @return number of dimensions
*/
public int getNoOfDimensions() {
return gnpCoordinates.length;
}
/**
*
* @param pos
* position in the coordinate array
* @return value at position pos
*/
public double getGnpCoordinates(int pos) {
return gnpCoordinates[pos];
}
/**
* Calculates the sum of all errors according to the downhill simplex
* operator.
*
* @return error
*/
public double getDownhillSimplexError() {
if (error < 0.0) {
error = 0.0;
for (int c = 0; c < getGnpRef().getNumberOfMonitors(); c++) {
error += getDownhillSimplexError(getGnpRef()
.getMonitorPosition(c));
}
}
return error;
}
/**
* Calculates the error to a monitor according to the downhill simplex
* operator
*
* @param monitor
* @return error
*/
public double getDownhillSimplexError(GnpPosition monitor) {
double calculatedDistance = this.distanceTo(monitor);
double measuredDistance = this.getMeasuredRtt(monitor);
if (Double.compare(measuredDistance, Double.NaN) == 0)
return 0.0;
double error = Math.pow((calculatedDistance - measuredDistance)
/ calculatedDistance, 2);
return error;
}
/**
* Calculates an error, that indicates the deviation of the measured vs. the
* calculated rtt.
*
* @param monitor
* @return error value
*/
public double getDirectionalRelativError(GnpPosition monitor) {
double calculatedDistance = this.distanceTo(monitor);
double measuredDistance = this.getMeasuredRtt(monitor);
if (Double.compare(measuredDistance, Double.NaN) == 0)
return Double.NaN;
double error = (calculatedDistance - measuredDistance)
/ Math.min(calculatedDistance, measuredDistance);
return error;
}
/**
* Method must be overwrite to sort different GnpPositions in order of their
* quality.
*
* Is needed for the positioning with the downhill simplex
*
*/
public int compareTo(GnpPosition arg0) {
double val1 = this.getDownhillSimplexError();
double val2 = arg0.getDownhillSimplexError();
if (val1 < val2)
return -1;
if (val1 > val2)
return 1;
else
return 0;
}
/**
*
* @return Comma-separated list of coordinates
*/
public String getCoordinateString() {
if (gnpCoordinates.length == 0) {
return "";
} else {
String result = String.valueOf(gnpCoordinates[0]);
for (int c = 1; c < gnpCoordinates.length; c++)
result = result + "," + gnpCoordinates[c];
return result;
}
}
/**
*
* @param monitor
* @return measured rtt to monitor, nan if no rtt was measured
*/
public double getMeasuredRtt(GnpPosition monitor) {
return this.getHostRef().getRtt(monitor.getHostRef());
}
/**
* @return euclidean distance
*/
public double getDistance(Location point) {
GnpPosition coord = (GnpPosition) point;
double distance = 0.0;
for (int c = 0; c < gnpCoordinates.length; c++)
distance += Math.pow(
gnpCoordinates[c] - coord.getGnpCoordinates(c), 2);
return Math.sqrt(distance);
}
@Override @Override
public int getTransmissionSize() { public int getTransmissionSize() {
return 16; // 2 * double return 16; // 2 * double
} }
/** /**
* Static method generates a new GnpPosition according to the downhill * Static method generates a new GnpPosition according to the downhill
* simplex operator * simplex operator
* *
* @param solution * @param solution
* @param moveToSolution * @param moveToSolution
* @param moveFactor * @param moveFactor
* @return new position * @return new position
*/ */
public static GnpPosition getMovedSolution(GnpPosition solution, public static GnpPosition getMovedSolution(GnpPosition solution,
GnpPosition moveToSolution, double moveFactor) { GnpPosition moveToSolution, double moveFactor) {
GnpPosition returnValue = new GnpPosition(solution.getNoOfDimensions(), GnpPosition returnValue = new GnpPosition(solution.getNoOfDimensions(),
solution.getHostRef(), solution.getGnpRef()); solution.getHostRef(), solution.getGnpRef());
for (int c = 0; c < solution.getNoOfDimensions(); c++) { for (int c = 0; c < solution.getNoOfDimensions(); c++) {
double newCoord = (moveToSolution.getGnpCoordinates(c) - solution double newCoord = (moveToSolution.getGnpCoordinates(c) - solution
.getGnpCoordinates(c)) .getGnpCoordinates(c))
* moveFactor + solution.getGnpCoordinates(c); * moveFactor + solution.getGnpCoordinates(c);
returnValue.setGnpCoordinates(c, newCoord); returnValue.setGnpCoordinates(c, newCoord);
} }
return returnValue; return returnValue;
} }
/** /**
* Static method generates a new GnpPosition according to the downhill * Static method generates a new GnpPosition according to the downhill
* simplex operator * simplex operator
* *
* @param solution * @param solution
* @param moveToSolution * @param moveToSolution
* @param moveFactor * @param moveFactor
* @return new position * @return new position
*/ */
public static GnpPosition getCenterSolution(ArrayList<GnpPosition> solutions) { public static GnpPosition getCenterSolution(ArrayList<GnpPosition> solutions) {
GnpPosition returnValue = new GnpPosition(solutions.get(0) GnpPosition returnValue = new GnpPosition(solutions.get(0)
.getNoOfDimensions(), solutions.get(0).getHostRef(), solutions .getNoOfDimensions(), solutions.get(0).getHostRef(), solutions
.get(0).getGnpRef()); .get(0).getGnpRef());
for (int d = 0; d < solutions.size(); d++) { for (int d = 0; d < solutions.size(); d++) {
for (int c = 0; c < solutions.get(0).getNoOfDimensions(); c++) { for (int c = 0; c < solutions.get(0).getNoOfDimensions(); c++) {
returnValue.setGnpCoordinates(c, returnValue returnValue.setGnpCoordinates(c, returnValue
.getGnpCoordinates(c) .getGnpCoordinates(c)
+ solutions.get(d).getGnpCoordinates(c)); + solutions.get(d).getGnpCoordinates(c));
} }
} }
for (int c = 0; c < returnValue.getNoOfDimensions(); c++) { for (int c = 0; c < returnValue.getNoOfDimensions(); c++) {
returnValue.setGnpCoordinates(c, returnValue.getGnpCoordinates(c) returnValue.setGnpCoordinates(c, returnValue.getGnpCoordinates(c)
/ solutions.size()); / solutions.size());
} }
return returnValue; return returnValue;
} }
public GnpPosition clone() { public GnpPosition clone() {
...@@ -323,7 +310,7 @@ public class GnpPosition implements Position, Comparable<GnpPosition> { ...@@ -323,7 +310,7 @@ public class GnpPosition implements Position, Comparable<GnpPosition> {
@Override @Override
public double distanceTo(Location dest) { public double distanceTo(Location dest) {
return getDistance((Position) dest); return getDistance(dest);
} }
@Override @Override
...@@ -344,5 +331,5 @@ public class GnpPosition implements Position, Comparable<GnpPosition> { ...@@ -344,5 +331,5 @@ public class GnpPosition implements Position, Comparable<GnpPosition> {
@Override @Override
public void set(Location l) { public void set(Location l) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
} }
...@@ -19,8 +19,8 @@ ...@@ -19,8 +19,8 @@
*/ */
package de.tud.kom.p2psim.impl.network.gnp.topology; package de.tud.kom.p2psim.impl.network.gnp.topology;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
...@@ -56,66 +56,66 @@ import de.tud.kom.p2psim.impl.network.modular.db.NetMeasurementDB.PingErRegion; ...@@ -56,66 +56,66 @@ import de.tud.kom.p2psim.impl.network.modular.db.NetMeasurementDB.PingErRegion;
import de.tud.kom.p2psim.impl.network.modular.db.NetMeasurementDB.Region; import de.tud.kom.p2psim.impl.network.modular.db.NetMeasurementDB.Region;
import de.tudarmstadt.maki.simonstrator.api.Monitor; import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.Monitor.Level; import de.tudarmstadt.maki.simonstrator.api.Monitor.Level;
/** /**
* This class holds all informations needed to built an xml-Host File for the * This class holds all informations needed to built an xml-Host File for the
* simulations with the GnpNetLayer and GnpLatencyModel * simulations with the GnpNetLayer and GnpLatencyModel
* *
* @author Gerald Klunker * @author Gerald Klunker
* @version 0.1, 05.02.2008 * @version 0.1, 05.02.2008
* *
*/ */
public class HostMap { public class HostMap {
private static final String GROUP_WORLD = "World"; private static final String GROUP_WORLD = "World";
private static final String COUNTRY_UNLOCATABLE = "#UNLOCATABLE_COUNTRY"; private static final String COUNTRY_UNLOCATABLE = "#UNLOCATABLE_COUNTRY";
private static final String REGION_UNLOCATABLE = "#UNLOCATABLE_REGION"; private static final String REGION_UNLOCATABLE = "#UNLOCATABLE_REGION";
private static final String PINGER_REGION_UNLOCATABLE = "#PINGER_REGION_UNLOCATABLE"; private static final String PINGER_REGION_UNLOCATABLE = "#PINGER_REGION_UNLOCATABLE";
// importet Files // importet Files
private HashMap<String, HashSet<Host>> skitterFiles = new HashMap<String, HashSet<Host>>(); private HashMap<String, HashSet<Host>> skitterFiles = new HashMap<String, HashSet<Host>>();
private File geolocationFile; private File geolocationFile;
private IspLookupService ispService; private IspLookupService ispService;
// Host Index and Groups // Host Index and Groups
private HashMap<Integer, Host> monitorIndex = new HashMap<Integer, Host>(); private HashMap<Integer, Host> monitorIndex = new HashMap<Integer, Host>();
private HashMap<Integer, Host> hostIndex = new HashMap<Integer, Host>(); private HashMap<Integer, Host> hostIndex = new HashMap<Integer, Host>();
private ArrayList<Host>[][][] quickLookup; private ArrayList<Host>[][][] quickLookup;
private HashMap<String, Set<Host>> groups = new HashMap<String, Set<Host>>(); private HashMap<String, Set<Host>> groups = new HashMap<String, Set<Host>>();
// Country - Region - PingEr dictionary // Country - Region - PingEr dictionary
private PingErLookup pingErLookup = new PingErLookup(); private PingErLookup pingErLookup = new PingErLookup();
private CountryLookup countryLookup = new CountryLookup(); private CountryLookup countryLookup = new CountryLookup();
private GnpSpace gnpRef; private GnpSpace gnpRef;
/** /**
* import Hosts and RTTs from a CAIDA skitter File * import Hosts and RTTs from a CAIDA skitter File
* *
* @param skitterFile * @param skitterFile
*/ */
public void importSkitterFile(File skitterFile, boolean oldFormat) { public void importSkitterFile(File skitterFile, boolean oldFormat) {
try { try {
skitterFiles.put(skitterFile.getAbsolutePath(), new HashSet<Host>()); skitterFiles.put(skitterFile.getAbsolutePath(), new HashSet<Host>());
FileReader inputFile = new FileReader(skitterFile); FileReader inputFile = new FileReader(skitterFile);
BufferedReader input = new BufferedReader(inputFile); BufferedReader input = new BufferedReader(inputFile);
int validLines = 0; int validLines = 0;
String line = input.readLine(); String line = input.readLine();
while (line != null) { while (line != null) {
if (line.length() < 1024) { if (line.length() < 1024) {
int commentbegin = line.indexOf("#"); int commentbegin = line.indexOf("#");
String line2parse = commentbegin < 0?line:line.substring(0, commentbegin); //ignore comments String line2parse = commentbegin < 0?line:line.substring(0, commentbegin); //ignore comments
...@@ -124,25 +124,25 @@ public class HostMap { ...@@ -124,25 +124,25 @@ public class HostMap {
if (!"".equals(line2parse.trim())) { if (!"".equals(line2parse.trim())) {
if(oldFormat?parseLineOldFormat(line2parse, skitterFile):parseLineNewFormat(line2parse, skitterFile)) validLines++; if(oldFormat?parseLineOldFormat(line2parse, skitterFile):parseLineNewFormat(line2parse, skitterFile)) validLines++;
} }
} else { } else {
//sometimes weird long lines occur when the file is corrupted: //sometimes weird long lines occur when the file is corrupted:
Monitor.log(HostMap.class, Level.ERROR, Monitor.log(HostMap.class, Level.ERROR,
"The weird long line with length " + line.length() "The weird long line with length " + line.length()
+ "' could not be parsed in skitter file " + "' could not be parsed in skitter file "
+ skitterFile); + skitterFile);
} }
line = input.readLine(); line = input.readLine();
} }
System.gc(); System.gc();
System.out.println("Imported " + validLines + " valid entries from skitter file " + skitterFile + "."); System.out.println("Imported " + validLines + " valid entries from skitter file " + skitterFile + ".");
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
e.printStackTrace(); e.printStackTrace();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
private boolean parseLineOldFormat(String line, File skitterFile) { private boolean parseLineOldFormat(String line, File skitterFile) {
int monitorIP; int monitorIP;
...@@ -241,889 +241,889 @@ public class HostMap { ...@@ -241,889 +241,889 @@ public class HostMap {
return false; return false;
} }
/** /**
* import PingER summary report File * import PingER summary report File
* *
* @param file * @param file
*/ */
public void importPingErMinimumRtt(File file) { public void importPingErMinimumRtt(File file) {
pingErLookup.loadFromTSV(file, PingErLookup.DataType.MIN_RTT); pingErLookup.loadFromTSV(file, PingErLookup.DataType.MIN_RTT);
} }
/** /**
* import PingER summary report File * import PingER summary report File
* *
* @param file * @param file
*/ */
public void importPingErAverageRtt(File file) { public void importPingErAverageRtt(File file) {
pingErLookup.loadFromTSV(file, PingErLookup.DataType.AVERAGE_RTT); pingErLookup.loadFromTSV(file, PingErLookup.DataType.AVERAGE_RTT);
} }
/** /**
* import PingER summary report File * import PingER summary report File
* *
* @param file * @param file
*/ */
public void importPingErDelayVariation(File file) { public void importPingErDelayVariation(File file) {
pingErLookup.loadFromTSV(file, PingErLookup.DataType.VARIATION_RTT); pingErLookup.loadFromTSV(file, PingErLookup.DataType.VARIATION_RTT);
} }
/** /**
* import PingER summary report File * import PingER summary report File
* *
* @param file * @param file
*/ */
public void importPingErPacketLoss(File file) { public void importPingErPacketLoss(File file) {
pingErLookup.loadFromTSV(file, PingErLookup.DataType.PACKET_LOSS); pingErLookup.loadFromTSV(file, PingErLookup.DataType.PACKET_LOSS);
} }
/** /**
* *
* @return country dictionary * @return country dictionary
*/ */
public CountryLookup getCountryLookup() { public CountryLookup getCountryLookup() {
return countryLookup; return countryLookup;
} }
/** /**
* *
* @return pingerEr lookup table * @return pingerEr lookup table
*/ */
public PingErLookup getPingErLookup() { public PingErLookup getPingErLookup() {
return pingErLookup; return pingErLookup;
} }
/** /**
* *
* @param longitude * @param longitude
* @param latitude * @param latitude
* @return set of the nearest hosts to longitude/latitude position * @return set of the nearest hosts to longitude/latitude position
*/ */
public Set<Host> getNearestHosts(double longitude, double latitude) { public Set<Host> getNearestHosts(double longitude, double latitude) {
HashSet<Host> result = new HashSet<Host>(); HashSet<Host> result = new HashSet<Host>();
int index0 = (int) Math.floor(HostMap.getGeographicalDistance(90, 0, latitude, longitude) / 1000.0); int index0 = (int) Math.floor(HostMap.getGeographicalDistance(90, 0, latitude, longitude) / 1000.0);
int index1 = (int) Math.floor(HostMap.getGeographicalDistance(0, 0, latitude, longitude) / 1000.0); int index1 = (int) Math.floor(HostMap.getGeographicalDistance(0, 0, latitude, longitude) / 1000.0);
int index2 = (int) Math.floor(HostMap.getGeographicalDistance(0, 90, latitude, longitude) / 1000.0); int index2 = (int) Math.floor(HostMap.getGeographicalDistance(0, 90, latitude, longitude) / 1000.0);
PeerComparatorDistance comparator = new PeerComparatorDistance(); PeerComparatorDistance comparator = new PeerComparatorDistance();
comparator.setPosition(latitude, longitude); comparator.setPosition(latitude, longitude);
Host peer = null; Host peer = null;
if (quickLookup != null && quickLookup[index0][index1][index2] != null) { if (quickLookup != null && quickLookup[index0][index1][index2] != null) {
for (Host p : quickLookup[index0][index1][index2]) { for (Host p : quickLookup[index0][index1][index2]) {
if (peer == null) { if (peer == null) {
peer = p; peer = p;
} else if (comparator.compare(peer, p) == 1) { } else if (comparator.compare(peer, p) == 1) {
peer = p; peer = p;
} }
} }
for (Host p : quickLookup[index0][index1][index2]) { for (Host p : quickLookup[index0][index1][index2]) {
if (comparator.compare(peer, p) == 0) if (comparator.compare(peer, p) == 0)
result.add(p); result.add(p);
} }
} }
return result; return result;
} }
/** /**
* rebuilt an array of hosts for fast finding of nearest hosts * rebuilt an array of hosts for fast finding of nearest hosts
*/ */
private void builtQuickLookup() { private void builtQuickLookup() {
quickLookup = new ArrayList[21][21][21]; quickLookup = new ArrayList[21][21][21];
int index0 = 0; int index0 = 0;
int index1 = 0; int index1 = 0;
int index2 = 0; int index2 = 0;
Set<Integer> ips = this.hostIndex.keySet(); Set<Integer> ips = this.hostIndex.keySet();
for (Integer ip : ips) { for (Integer ip : ips) {
index0 = (int) Math.floor(HostMap.getGeographicalDistance(90, 0, hostIndex.get(ip).getLatitude(), hostIndex.get(ip).getLongitude()) / 1000.0); index0 = (int) Math.floor(HostMap.getGeographicalDistance(90, 0, hostIndex.get(ip).getLatitude(), hostIndex.get(ip).getLongitude()) / 1000.0);
index1 = (int) Math.floor(HostMap.getGeographicalDistance(0, 0, hostIndex.get(ip).getLatitude(), hostIndex.get(ip).getLongitude()) / 1000.0); index1 = (int) Math.floor(HostMap.getGeographicalDistance(0, 0, hostIndex.get(ip).getLatitude(), hostIndex.get(ip).getLongitude()) / 1000.0);
index2 = (int) Math.floor(HostMap.getGeographicalDistance(0, 90, hostIndex.get(ip).getLatitude(), hostIndex.get(ip).getLongitude()) / 1000.0); index2 = (int) Math.floor(HostMap.getGeographicalDistance(0, 90, hostIndex.get(ip).getLatitude(), hostIndex.get(ip).getLongitude()) / 1000.0);
if (quickLookup[index0][index1][index2] == null) if (quickLookup[index0][index1][index2] == null)
quickLookup[index0][index1][index2] = new ArrayList<Host>(); quickLookup[index0][index1][index2] = new ArrayList<Host>();
quickLookup[index0][index1][index2].add(hostIndex.get(ip)); quickLookup[index0][index1][index2].add(hostIndex.get(ip));
} }
} }
/** /**
* *
* @return reference to the related GNP Space object * @return reference to the related GNP Space object
*/ */
public GnpSpace getGnpRef() { public GnpSpace getGnpRef() {
return gnpRef; return gnpRef;
} }
/** /**
* *
* @param gnp * @param gnp
* reference to the related GNP Space object * reference to the related GNP Space object
*/ */
public void setGnpRef(GnpSpace gnp) { public void setGnpRef(GnpSpace gnp) {
gnpRef = gnp; gnpRef = gnp;
} }
/** /**
* *
* @return map of importet skitter files and hosts * @return map of importet skitter files and hosts
*/ */
public HashMap<String, HashSet<Host>> getImportedSkitterFiles() { public HashMap<String, HashSet<Host>> getImportedSkitterFiles() {
return skitterFiles; return skitterFiles;
} }
/** /**
* counts the number of hosts with a certain number of measured RTTs [0]: * counts the number of hosts with a certain number of measured RTTs [0]:
* number of Hosts with 0 measured RTTs, [1] number of Hosts with 1 measured * number of Hosts with 0 measured RTTs, [1] number of Hosts with 1 measured
* RTTs ... * RTTs ...
* *
* @return map from number of measured RTTs to number of related hosts * @return map from number of measured RTTs to number of related hosts
*/ */
public int[] getConnectivityOfHosts() { public int[] getConnectivityOfHosts() {
int[] counter = new int[getNoOfMonitors() + 1]; int[] counter = new int[getNoOfMonitors() + 1];
for (Host host : hostIndex.values()) { for (Host host : hostIndex.values()) {
if (host.getHostType() == Host.HOST) if (host.getHostType() == Host.HOST)
counter[host.getMeasuredMonitors().size()]++; counter[host.getMeasuredMonitors().size()]++;
} }
return counter; return counter;
} }
/** /**
* *
* @param groupName * @param groupName
* @return Set of Host related to the Group * @return Set of Host related to the Group
*/ */
public Collection<Host> getGroup(String groupName) { public Collection<Host> getGroup(String groupName) {
if (groups.containsKey(groupName)) if (groups.containsKey(groupName))
return groups.get(groupName); return groups.get(groupName);
else else
return new HashSet<Host>(); return new HashSet<Host>();
} }
/** /**
* *
* @return map of groupnames to related hosts * @return map of groupnames to related hosts
*/ */
public HashMap<String, Set<Host>> getGroups() { public HashMap<String, Set<Host>> getGroups() {
return groups; return groups;
} }
/** /**
* *
* @param groupName * @param groupName
* @param host * @param host
*/ */
public void addHostToGroup(String groupName, Host host) { public void addHostToGroup(String groupName, Host host) {
String name = groupName.replace(" ", ""); String name = groupName.replace(" ", "");
if (!groups.containsKey(name)) if (!groups.containsKey(name))
groups.put(name, new HashSet<Host>()); groups.put(name, new HashSet<Host>());
groups.get(name).add(host); groups.get(name).add(host);
} }
/** /**
* *
* @param groupName * @param groupName
* @param hosts * @param hosts
* set of hosts * set of hosts
*/ */
public void addHostToGroup(String groupName, Collection<Host> hosts) { public void addHostToGroup(String groupName, Collection<Host> hosts) {
String name = groupName.replace(" ", ""); String name = groupName.replace(" ", "");
if (!groups.containsKey(name)) if (!groups.containsKey(name))
groups.put(name, new HashSet<Host>()); groups.put(name, new HashSet<Host>());
groups.get(name).addAll(hosts); groups.get(name).addAll(hosts);
} }
/** /**
* *
* @param groupName * @param groupName
* @param grid * @param grid
*/ */
public void addHostToGroup(String groupName, boolean grid[][]) { public void addHostToGroup(String groupName, boolean grid[][]) {
Set<Host>[][] peerGrid = getHostGrid(grid.length, grid[0].length); Set<Host>[][] peerGrid = getHostGrid(grid.length, grid[0].length);
for (int x = 0; x < grid.length; x++) { for (int x = 0; x < grid.length; x++) {
for (int y = 0; y < grid[x].length; y++) { for (int y = 0; y < grid[x].length; y++) {
if (grid[x][y]) { if (grid[x][y]) {
addHostToGroup(groupName, peerGrid[x][y]); addHostToGroup(groupName, peerGrid[x][y]);
} }
} }
} }
} }
/** /**
* *
* @param resLon * @param resLon
* number of horizontal divisions * number of horizontal divisions
* @param resLat * @param resLat
* number of vertical divisions * number of vertical divisions
* @return hosts grouped by their geographical position * @return hosts grouped by their geographical position
*/ */
private Set<Host>[][] getHostGrid(int resLon, int resLat) { private Set<Host>[][] getHostGrid(int resLon, int resLat) {
Set<Host>[][] peerGrid = new HashSet[resLon][resLat]; Set<Host>[][] peerGrid = new HashSet[resLon][resLat];
int posLon; int posLon;
int posLat; int posLat;
double stepLon = 360 / (double) resLon; double stepLon = 360 / (double) resLon;
double stepLat = 180 / (double) resLat; double stepLat = 180 / (double) resLat;
for (Host host : hostIndex.values()) { for (Host host : hostIndex.values()) {
posLon = (int) Math.floor((180 + host.getLongitude()) / stepLon); posLon = (int) Math.floor((180 + host.getLongitude()) / stepLon);
posLat = (int) Math.floor((90 + host.getLatitude()) / stepLat); posLat = (int) Math.floor((90 + host.getLatitude()) / stepLat);
if (peerGrid[posLon][posLat] == null) if (peerGrid[posLon][posLat] == null)
peerGrid[posLon][posLat] = new HashSet<Host>(); peerGrid[posLon][posLat] = new HashSet<Host>();
peerGrid[posLon][posLat].add(host); peerGrid[posLon][posLat].add(host);
} }
return peerGrid; return peerGrid;
} }
/** /**
* *
* @param groupName * @param groupName
*/ */
public void removeGroup(String groupName) { public void removeGroup(String groupName) {
groups.remove(groupName); groups.remove(groupName);
} }
/** /**
* *
* @param groupNames * @param groupNames
* set of group names * set of group names
*/ */
public void removeGroup(Set<String> groupNames) { public void removeGroup(Set<String> groupNames) {
for (String name : groupNames) for (String name : groupNames)
removeGroup(name); removeGroup(name);
} }
/** /**
* reduce the number of hosts in a group * reduce the number of hosts in a group
* *
* @param groupName * @param groupName
* @param noOfHosts * @param noOfHosts
*/ */
public void scaleGroup(String groupName, int newSize) { public void scaleGroup(String groupName, int newSize) {
Set<Host> oldGroup = groups.get(groupName); Set<Host> oldGroup = groups.get(groupName);
Set<Host> newGroup = new HashSet<Host>(); Set<Host> newGroup = new HashSet<Host>();
while (newGroup.size() < newSize && oldGroup.size() > 0) { while (newGroup.size() < newSize && oldGroup.size() > 0) {
Host[] hosts = oldGroup.toArray(new Host[0]); Host[] hosts = oldGroup.toArray(new Host[0]);
for (int c = 0; c < newSize - newGroup.size(); c++) { for (int c = 0; c < newSize - newGroup.size(); c++) {
int random = (int) Math.floor(Math.random() * hosts.length); int random = (int) Math.floor(Math.random() * hosts.length);
newGroup.add(hosts[random]); newGroup.add(hosts[random]);
oldGroup.remove(hosts[random]); oldGroup.remove(hosts[random]);
} }
} }
oldGroup.clear(); oldGroup.clear();
oldGroup.addAll(newGroup); oldGroup.addAll(newGroup);
} }
/** /**
* generate groups with the name of GeoIP country names * generate groups with the name of GeoIP country names
*/ */
public void builtCountryGroups() { public void builtCountryGroups() {
for (Host host : hostIndex.values()) { for (Host host : hostIndex.values()) {
String country = countryLookup.getGeoIpCountryName(host.getCountryCode()); String country = countryLookup.getGeoIpCountryName(host.getCountryCode());
if (country == null) if (country == null)
country = COUNTRY_UNLOCATABLE; country = COUNTRY_UNLOCATABLE;
this.addHostToGroup(country, host); this.addHostToGroup(country, host);
} }
} }
/** /**
* generate groups with the name of GeoIP country names * generate groups with the name of GeoIP country names
*/ */
public void builtRegionGroups() { public void builtRegionGroups() {
for (Host host : hostIndex.values()) { for (Host host : hostIndex.values()) {
String region = host.getRegion(); String region = host.getRegion();
if (region == null) if (region == null)
region = REGION_UNLOCATABLE; region = REGION_UNLOCATABLE;
this.addHostToGroup(region, host); this.addHostToGroup(region, host);
} }
} }
/** /**
* generate groups with the name of PingER region names * generate groups with the name of PingER region names
*/ */
public void builtPingerGroups() { public void builtPingerGroups() {
for (Host host : hostIndex.values()) { for (Host host : hostIndex.values()) {
String country = countryLookup.getPingErRegionName(host.getCountryCode()); String country = countryLookup.getPingErRegionName(host.getCountryCode());
if (country == null) if (country == null)
country = PINGER_REGION_UNLOCATABLE; country = PINGER_REGION_UNLOCATABLE;
this.addHostToGroup(country, host); this.addHostToGroup(country, host);
} }
} }
/** /**
* built a group with all hosts * built a group with all hosts
*/ */
public void builtWorldGroups() { public void builtWorldGroups() {
this.addHostToGroup(GROUP_WORLD, hostIndex.values()); this.addHostToGroup(GROUP_WORLD, hostIndex.values());
} }
/** /**
* *
* @return number of hosts in this map * @return number of hosts in this map
*/ */
public int getNoOfHosts() { public int getNoOfHosts() {
return hostIndex.size(); return hostIndex.size();
} }
/** /**
* *
* @return number of monitors in this map * @return number of monitors in this map
*/ */
public int getNoOfMonitors() { public int getNoOfMonitors() {
return monitorIndex.size(); return monitorIndex.size();
} }
/** /**
* *
* @param file * @param file
* filename of a GeoIP binary database * filename of a GeoIP binary database
*/ */
public void setGeolocationDatabase(File file) { public void setGeolocationDatabase(File file) {
geolocationFile = file; geolocationFile = file;
} }
public void setIspLocationDatabase(String db) { public void setIspLocationDatabase(String db) {
ispService = new IspLookupService(db); ispService = new IspLookupService(db);
} }
/** /**
* *
* @return filename of the current GeoIP database * @return filename of the current GeoIP database
*/ */
public File getGeolocationDatabase() { public File getGeolocationDatabase() {
return geolocationFile; return geolocationFile;
} }
/** /**
* position all hosts with the current GeoIP database * position all hosts with the current GeoIP database
*/ */
public void setLocationOfHosts() { public void setLocationOfHosts() {
if (geolocationFile == null) { if (geolocationFile == null) {
return; return;
} }
Geolocator locator = new GeolocatorGeoIP(geolocationFile); Geolocator locator = new GeolocatorGeoIP(geolocationFile);
for (Host host : hostIndex.values()) { for (Host host : hostIndex.values()) {
host.setLocation(locator, ispService); host.setLocation(locator, ispService);
} }
builtQuickLookup(); builtQuickLookup();
// distanceVsRttPlot("test100", null, 100); // distanceVsRttPlot("test100", null, 100);
} }
/** /**
* *
* @return map from 2-digits country code to the related hosts * @return map from 2-digits country code to the related hosts
*/ */
public HashMap<String, HashSet<Host>> getLocations() { public HashMap<String, HashSet<Host>> getLocations() {
HashMap<String, HashSet<Host>> locations = new HashMap<String, HashSet<Host>>(); HashMap<String, HashSet<Host>> locations = new HashMap<String, HashSet<Host>>();
locations.put("# LOCATABLE", new HashSet<Host>()); locations.put("# LOCATABLE", new HashSet<Host>());
locations.put("# UNLOCATABLE", new HashSet<Host>()); locations.put("# UNLOCATABLE", new HashSet<Host>());
for (Host host : hostIndex.values()) { for (Host host : hostIndex.values()) {
if (host.isLocatable()) { if (host.isLocatable()) {
if (!locations.containsKey(host.getCountryCode())) if (!locations.containsKey(host.getCountryCode()))
locations.put(host.getCountryCode(), new HashSet<Host>()); locations.put(host.getCountryCode(), new HashSet<Host>());
locations.get(host.getCountryCode()).add(host); locations.get(host.getCountryCode()).add(host);
locations.get("# LOCATABLE").add(host); locations.get("# LOCATABLE").add(host);
} else { } else {
locations.get("# UNLOCATABLE").add(host); locations.get("# UNLOCATABLE").add(host);
} }
} }
return locations; return locations;
} }
/** /**
* *
* @return map from ip to related monitor Host object * @return map from ip to related monitor Host object
*/ */
public HashMap<Integer, Host> getMonitorIndex() { public HashMap<Integer, Host> getMonitorIndex() {
return monitorIndex; return monitorIndex;
} }
/** /**
* *
* @return map from ip to related Host object * @return map from ip to related Host object
*/ */
public HashMap<Integer, Host> getHostIndex() { public HashMap<Integer, Host> getHostIndex() {
return hostIndex; return hostIndex;
} }
/** /**
* make the measured inter-monitor RTTs adjacency matrix symmetrical. => RTT * make the measured inter-monitor RTTs adjacency matrix symmetrical. => RTT
* A->B = RTT B->A assumtion is needed within the GNP coordinate model. * A->B = RTT B->A assumtion is needed within the GNP coordinate model.
*/ */
public void makeSymmetrical() { public void makeSymmetrical() {
for (Host monitorA : monitorIndex.values()) { for (Host monitorA : monitorIndex.values()) {
for (Host monitorB : monitorIndex.values()) { for (Host monitorB : monitorIndex.values()) {
if (monitorA == monitorB) { if (monitorA == monitorB) {
monitorA.removeRTT(monitorB); monitorA.removeRTT(monitorB);
} else { } else {
double rtt1 = monitorA.getRtt(monitorB); double rtt1 = monitorA.getRtt(monitorB);
double rtt2 = monitorB.getRtt(monitorA); double rtt2 = monitorB.getRtt(monitorA);
double newRtt = Double.NaN; double newRtt = Double.NaN;
if (rtt1 > 0 && rtt2 > 0) if (rtt1 > 0 && rtt2 > 0)
newRtt = (rtt1 + rtt2) / 2; newRtt = (rtt1 + rtt2) / 2;
else if (rtt1 > 0) else if (rtt1 > 0)
newRtt = rtt1; newRtt = rtt1;
else if (rtt2 > 0) else if (rtt2 > 0)
newRtt = rtt2; newRtt = rtt2;
monitorA.setRtt(monitorB, newRtt); monitorA.setRtt(monitorB, newRtt);
monitorB.setRtt(monitorA, newRtt); monitorB.setRtt(monitorA, newRtt);
} }
} }
} }
} }
/** /**
* *
* @param p1 * @param p1
* host 1 * host 1
* @param p2 * @param p2
* host 2 * host 2
* @return distance in km * @return distance in km
*/ */
private static double getGeographicalDistance(Host p1, Host p2) { private static double getGeographicalDistance(Host p1, Host p2) {
return HostMap.getGeographicalDistance(p1.getLatitude(), p1.getLongitude(), p2.getLatitude(), p2.getLongitude()); return HostMap.getGeographicalDistance(p1.getLatitude(), p1.getLongitude(), p2.getLatitude(), p2.getLongitude());
} }
/** /**
* *
* @param latitude1 * @param latitude1
* host 1 * host 1
* @param longitude1 * @param longitude1
* host 1 * host 1
* @param latitude2 * @param latitude2
* host 2 * host 2
* @param longitude2 * @param longitude2
* host 2 * host 2
* @return distance in km * @return distance in km
*/ */
private static double getGeographicalDistance(double latitude1, double longitude1, double latitude2, double longitude2) { private static double getGeographicalDistance(double latitude1, double longitude1, double latitude2, double longitude2) {
GeographicPosition pos1 = new GeographicPosition(longitude1, latitude1); GeographicPosition pos1 = new GeographicPosition(longitude1, latitude1);
GeographicPosition pos2 = new GeographicPosition(longitude2, latitude2); GeographicPosition pos2 = new GeographicPosition(longitude2, latitude2);
return pos1.getDistance(pos2); return pos1.distanceTo(pos2);
} }
/** /**
* unlocatable on the globe (unkonw ip, proxy, satelite) * unlocatable on the globe (unkonw ip, proxy, satelite)
* *
* @return number of unlocatable hosts * @return number of unlocatable hosts
*/ */
public int getNoOfUnlocatableHosts() { public int getNoOfUnlocatableHosts() {
int unlocatedPeers = 0; int unlocatedPeers = 0;
int unlocatedMonitors = 0; int unlocatedMonitors = 0;
Set<Integer> ips = this.hostIndex.keySet(); Set<Integer> ips = this.hostIndex.keySet();
for (Integer ip : ips) { for (Integer ip : ips) {
unlocatedPeers += (hostIndex.get(ip).isLocatable()) ? 0 : 1; unlocatedPeers += (hostIndex.get(ip).isLocatable()) ? 0 : 1;
unlocatedMonitors += (hostIndex.get(ip).isLocatable() || hostIndex.get(ip).getHostType() == Host.HOST) ? 0 : 1; unlocatedMonitors += (hostIndex.get(ip).isLocatable() || hostIndex.get(ip).getHostType() == Host.HOST) ? 0 : 1;
} }
return unlocatedPeers - unlocatedMonitors; return unlocatedPeers - unlocatedMonitors;
} }
/** /**
* *
* @param monitor * @param monitor
*/ */
public void removeMonitor(Host monitor) { public void removeMonitor(Host monitor) {
this.monitorIndex.remove(monitor.getIpAddress()); this.monitorIndex.remove(monitor.getIpAddress());
this.hostIndex.remove(monitor.getIpAddress()); this.hostIndex.remove(monitor.getIpAddress());
for (Host host : hostIndex.values()) { for (Host host : hostIndex.values()) {
host.removeRTT(monitor); host.removeRTT(monitor);
} }
this.builtQuickLookup(); this.builtQuickLookup();
} }
/** /**
* *
* Removes the given set of hosts from the map. * Removes the given set of hosts from the map.
* *
* @param hosts * @param hosts
* set of hosts * set of hosts
*/ */
public void removeHosts(Set<Host> hosts) { public void removeHosts(Set<Host> hosts) {
for (Host host : hosts) { for (Host host : hosts) {
// if (host.getHostType() == Host.HOST) { // if (host.getHostType() == Host.HOST) {
if (this.getGnpRef() != null) if (this.getGnpRef() != null)
this.getGnpRef().removePosition(host.getIpAddress()); this.getGnpRef().removePosition(host.getIpAddress());
this.hostIndex.remove(host.getIpAddress()); this.hostIndex.remove(host.getIpAddress());
// } // }
} }
for (Set<Host> group : groups.values()) for (Set<Host> group : groups.values())
group.removeAll(hosts); group.removeAll(hosts);
countryLookup.keepCountries(getLocations().keySet()); countryLookup.keepCountries(getLocations().keySet());
this.builtQuickLookup(); this.builtQuickLookup();
} }
/** /**
* SEEMS TO remove all hosts that were pinged by exactly noOfConnections * SEEMS TO remove all hosts that were pinged by exactly noOfConnections
* distinct monitors. * distinct monitors.
* *
* removes all hosts that have noOfConnections measured RTTs * removes all hosts that have noOfConnections measured RTTs
* *
* @param noOfConnections * @param noOfConnections
*/ */
public void removeHosts(int noOfConnections) { public void removeHosts(int noOfConnections) {
Set<Host> hosts = new HashSet<Host>(); Set<Host> hosts = new HashSet<Host>();
for (Host host : hostIndex.values()) { for (Host host : hostIndex.values()) {
if (host.getMeasuredMonitors().size() == noOfConnections) if (host.getMeasuredMonitors().size() == noOfConnections)
hosts.add(host); hosts.add(host);
} }
removeHosts(hosts); removeHosts(hosts);
} }
/** /**
* remove all hosts that have at least one measured RTT with a error bigger * remove all hosts that have at least one measured RTT with a error bigger
* than the argument. Removing that errors will improve the quality of the * than the argument. Removing that errors will improve the quality of the
* Gnp Space. * Gnp Space.
* *
* @param error * @param error
* relative error * relative error
*/ */
public void removeHostsWithMaximumRelativeError(double error) { public void removeHostsWithMaximumRelativeError(double error) {
HashSet<Host> delete = new HashSet<Host>(); HashSet<Host> delete = new HashSet<Host>();
for (Host host : hostIndex.values()) { for (Host host : hostIndex.values()) {
for (int c = 0; c < gnpRef.getNumberOfMonitors(); c++) { for (int c = 0; c < gnpRef.getNumberOfMonitors(); c++) {
double relError = Math.abs(host.getGnpPositionReference().getDirectionalRelativError(gnpRef.getMonitorPosition(c))); double relError = Math.abs(host.getGnpPositionReference().getDirectionalRelativError(gnpRef.getMonitorPosition(c)));
if (relError >= error) { if (relError >= error) {
delete.add(host); delete.add(host);
break; break;
} }
} }
} }
removeHosts(delete); removeHosts(delete);
} }
/** /**
* SEEMS TO only keep the 'noOfMonitorsToKeep' monitor hosts in the GNP space that have the * SEEMS TO only keep the 'noOfMonitorsToKeep' monitor hosts in the GNP space that have the
* maximum distance between each other, the other ones are being deleted. * maximum distance between each other, the other ones are being deleted.
*
* keeps the maximum separated monitors
*
* @param noOfMonitorsToKeep
*/
public void removeMonitorsKeepMaximumSparation(int noOfMonitorsToKeep) {
ArrayList<Host> maxSeperatedPeers = getMaximumSeparatedMonitors(noOfMonitorsToKeep);
ArrayList<Host> deleteMonitors = new ArrayList<Host>();
for (Host monitor : monitorIndex.values()) {
if (!maxSeperatedPeers.contains(monitor))
deleteMonitors.add(monitor);
}
for (Host monitor : deleteMonitors) {
this.removeMonitor(monitor);
}
}
/**
* *
* * keeps the maximum separated monitors
* @param noOfMonitors *
* @return maximum separated monitors * @param noOfMonitorsToKeep
*/ */
private ArrayList<Host> getMaximumSeparatedMonitors(int noOfMonitors) { public void removeMonitorsKeepMaximumSparation(int noOfMonitorsToKeep) {
ArrayList<ArrayList<Host>> allCombinations = getMonitorCombinations(noOfMonitors); ArrayList<Host> maxSeperatedPeers = getMaximumSeparatedMonitors(noOfMonitorsToKeep);
int posWithMax = 0; ArrayList<Host> deleteMonitors = new ArrayList<Host>();
double valueMax = 0.0; for (Host monitor : monitorIndex.values()) {
for (int c = 0; c < allCombinations.size(); c++) { if (!maxSeperatedPeers.contains(monitor))
double currentDistance = getInterMonitorDistance(allCombinations.get(c)); deleteMonitors.add(monitor);
if (currentDistance > valueMax) { }
valueMax = currentDistance; for (Host monitor : deleteMonitors) {
posWithMax = c; this.removeMonitor(monitor);
} }
} }
return allCombinations.get(posWithMax);
} /**
*
/** *
* * @param noOfMonitors
* @param monitors * @return maximum separated monitors
* @return sum measured RTTs between monitors */
*/ private ArrayList<Host> getMaximumSeparatedMonitors(int noOfMonitors) {
private double getInterMonitorDistance(ArrayList<Host> monitors) { ArrayList<ArrayList<Host>> allCombinations = getMonitorCombinations(noOfMonitors);
double result = 0.0; int posWithMax = 0;
for (int c = 0; c < monitors.size() - 1; c++) double valueMax = 0.0;
for (int d = c + 1; d < monitors.size(); d++) for (int c = 0; c < allCombinations.size(); c++) {
result += monitors.get(c).getRtt(monitors.get(d)); double currentDistance = getInterMonitorDistance(allCombinations.get(c));
return result; if (currentDistance > valueMax) {
valueMax = currentDistance;
} posWithMax = c;
}
/** }
* return allCombinations.get(posWithMax);
* @param size }
* @return all combinations of monitors with size "size"
*/ /**
private ArrayList<ArrayList<Host>> getMonitorCombinations(int size) { *
ArrayList<Host> monitors = new ArrayList<Host>(); * @param monitors
monitors.addAll(monitorIndex.values()); * @return sum measured RTTs between monitors
Collections.sort(monitors, new PeerComparatorNoOfConnections()); */
return builtRecursive(new ArrayList<Host>(), size, monitors, 0); private double getInterMonitorDistance(ArrayList<Host> monitors) {
} double result = 0.0;
for (int c = 0; c < monitors.size() - 1; c++)
/** for (int d = c + 1; d < monitors.size(); d++)
* recursive built of all combinations of monitors with size "size" result += monitors.get(c).getRtt(monitors.get(d));
* return result;
* @param current
* @param max }
* @param monitors
* @param posInMonitors /**
* @return array of combinations *
*/ * @param size
private ArrayList<ArrayList<Host>> builtRecursive(ArrayList<Host> current, int max, ArrayList<Host> monitors, int posInMonitors) { * @return all combinations of monitors with size "size"
ArrayList<ArrayList<Host>> result = new ArrayList<ArrayList<Host>>(); */
if (current.size() == max) { private ArrayList<ArrayList<Host>> getMonitorCombinations(int size) {
result.add(current); ArrayList<Host> monitors = new ArrayList<Host>();
return result; monitors.addAll(monitorIndex.values());
} else { Collections.sort(monitors, new PeerComparatorNoOfConnections());
for (int c = posInMonitors; c < monitors.size() - (max - current.size()); c++) { return builtRecursive(new ArrayList<Host>(), size, monitors, 0);
ArrayList<Host> copy = (ArrayList<Host>) current.clone(); }
copy.add(monitors.get(c));
result.addAll(builtRecursive(copy, max, monitors, c + 1)); /**
} * recursive built of all combinations of monitors with size "size"
return result; *
} * @param current
} * @param max
* @param monitors
/** * @param posInMonitors
* generate two files with distance - rtt pairs, that can be used with * @return array of combinations
* gnuplot */
* private ArrayList<ArrayList<Host>> builtRecursive(ArrayList<Host> current, int max, ArrayList<Host> monitors, int posInMonitors) {
* filename.txt1 plots each measured host - monitor RTT filename.txt2 ArrayList<ArrayList<Host>> result = new ArrayList<ArrayList<Host>>();
* aggregates distances within a range and calculates the average RTT if (current.size() == max) {
* result.add(current);
* @param filename return result;
* @param steps } else {
* number of divisions within the 0 - 20000km for aggregated plot for (int c = posInMonitors; c < monitors.size() - (max - current.size()); c++) {
*/ ArrayList<Host> copy = (ArrayList<Host>) current.clone();
public void distanceVsRttPlot(String filename, Host monitor, int steps) { copy.add(monitors.get(c));
try { result.addAll(builtRecursive(copy, max, monitors, c + 1));
double[] test1 = new double[steps]; }
int[] test2 = new int[steps]; return result;
}
FileWriter all = new FileWriter(filename + ".txt1"); }
for (Host host : hostIndex.values()) {
for (Host mon : host.getMeasuredMonitors()) { /**
double distance = getGeographicalDistance(host, mon); * generate two files with distance - rtt pairs, that can be used with
double rtt = host.getRtt(mon); * gnuplot
all.write(distance + " " + rtt + "\n"); *
* filename.txt1 plots each measured host - monitor RTT filename.txt2
int pos = (int) Math.floor((distance / 20000.0) * steps); * aggregates distances within a range and calculates the average RTT
test1[pos] += rtt; *
test2[pos]++; * @param filename
} * @param steps
} * number of divisions within the 0 - 20000km for aggregated plot
all.close(); */
all = new FileWriter(filename + ".txt2"); public void distanceVsRttPlot(String filename, Host monitor, int steps) {
for (int c = 0; c < steps; c++) { try {
double x = (c * (20000.0 / steps)) + (20000.0 / (2 * steps)); double[] test1 = new double[steps];
double y = test1[c] / test2[c]; int[] test2 = new int[steps];
all.write(x + " " + y + "\n");
} FileWriter all = new FileWriter(filename + ".txt1");
all.close(); for (Host host : hostIndex.values()) {
for (Host mon : host.getMeasuredMonitors()) {
} catch (IOException e) { double distance = getGeographicalDistance(host, mon);
e.printStackTrace(); double rtt = host.getRtt(mon);
} all.write(distance + " " + rtt + "\n");
}
int pos = (int) Math.floor((distance / 20000.0) * steps);
/** test1[pos] += rtt;
* saves host postion location, GNP position, groups, GNP Space, PingER test2[pos]++;
* Lookup table in an xml file used within the simulation }
* }
* @param file all.close();
*/ all = new FileWriter(filename + ".txt2");
public void exportToXml(File file) { for (int c = 0; c < steps; c++) {
try { double x = (c * (20000.0 / steps)) + (20000.0 / (2 * steps));
OutputFormat format = OutputFormat.createPrettyPrint(); double y = test1[c] / test2[c];
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(file), "UTF-8"); all.write(x + " " + y + "\n");
XMLWriter writer = new XMLWriter(out, format); }
writer.write(getDocument()); all.close();
writer.close();
} catch (IOException e) { } catch (IOException e) {
System.out.println(e); e.printStackTrace();
} }
} }
/** /**
* * saves host postion location, GNP position, groups, GNP Space, PingER
* @return xml Document Object of relevant Class Attributes * Lookup table in an xml file used within the simulation
*/ *
private Document getDocument() { * @param file
Set<Host> hosts = new HashSet<Host>(); */
public void exportToXml(File file) {
// "GroupLookup" Element try {
DefaultElement groups = new DefaultElement("GroupLookup"); OutputFormat format = OutputFormat.createPrettyPrint();
for (String group : this.groups.keySet()) { OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
hosts.addAll(this.groups.get(group)); XMLWriter writer = new XMLWriter(out, format);
DefaultElement peerXml = new DefaultElement("Group"); writer.write(getDocument());
peerXml.addAttribute("id", group); writer.close();
peerXml.addAttribute("maxsize", String.valueOf(this.groups.get(group).size())); } catch (IOException e) {
String ip = ""; System.out.println(e);
int x = 0; }
int blockSize = 1000; }
// IP Block of 1000, too long blocks leads to hangUp ??
for (Host host : this.groups.get(group)) { /**
x++; *
ip += "," + host.getIpAddress(); * @return xml Document Object of relevant Class Attributes
if (x % blockSize == 0) { */
ip = ip.substring(1); private Document getDocument() {
DefaultElement ips = new DefaultElement("IPs"); Set<Host> hosts = new HashSet<Host>();
ips.addAttribute("value", ip);
peerXml.add(ips); // "GroupLookup" Element
ip = ""; DefaultElement groups = new DefaultElement("GroupLookup");
} for (String group : this.groups.keySet()) {
} hosts.addAll(this.groups.get(group));
if (ip.length() > 0) { DefaultElement peerXml = new DefaultElement("Group");
ip = ip.substring(1); peerXml.addAttribute("id", group);
DefaultElement ips = new DefaultElement("IPs"); peerXml.addAttribute("maxsize", String.valueOf(this.groups.get(group).size()));
ips.addAttribute("value", ip); String ip = "";
peerXml.add(ips); int x = 0;
} int blockSize = 1000;
groups.add(peerXml); // IP Block of 1000, too long blocks leads to hangUp ??
} for (Host host : this.groups.get(group)) {
x++;
// "Hosts" Element ip += "," + host.getIpAddress();
DefaultElement peers = new DefaultElement("Hosts"); if (x % blockSize == 0) {
for (Host host : hosts) { ip = ip.substring(1);
DefaultElement peer = new DefaultElement("Host"); DefaultElement ips = new DefaultElement("IPs");
peer.addAttribute("ip", String.valueOf(host.getIpAddress())); ips.addAttribute("value", ip);
peerXml.add(ips);
String area = (host.getArea() != null) ? host.getArea() : "--"; ip = "";
peer.addAttribute("continentalArea", area); }
}
String countryCode = (host.getCountryCode() != null) ? host.getCountryCode() : "--"; if (ip.length() > 0) {
peer.addAttribute("countryCode", countryCode); ip = ip.substring(1);
DefaultElement ips = new DefaultElement("IPs");
String region = (host.getRegion() != null) ? host.getRegion() : "--"; ips.addAttribute("value", ip);
peer.addAttribute("region", region); peerXml.add(ips);
}
String city = (host.getCity() != null) ? host.getCity() : "--"; groups.add(peerXml);
peer.addAttribute("city", city); }
String isp = (host.getISP() != null) ? host.getISP() : "--"; // "Hosts" Element
peer.addAttribute("isp", isp); DefaultElement peers = new DefaultElement("Hosts");
for (Host host : hosts) {
peer.addAttribute("longitude", String.valueOf(host.getLongitude())); DefaultElement peer = new DefaultElement("Host");
peer.addAttribute("latitude", String.valueOf(host.getLatitude())); peer.addAttribute("ip", String.valueOf(host.getIpAddress()));
String coordinates = (host.getGnpPositionReference() != null) ? host.getGnpPositionReference().getCoordinateString() : "0";
peer.addAttribute("coordinates", coordinates); String area = (host.getArea() != null) ? host.getArea() : "--";
peers.add(peer); peer.addAttribute("continentalArea", area);
}
String countryCode = (host.getCountryCode() != null) ? host.getCountryCode() : "--";
// "PingErLookup" Elements peer.addAttribute("countryCode", countryCode);
Element pingEr = pingErLookup.exportToXML();
String region = (host.getRegion() != null) ? host.getRegion() : "--";
// "CountryLookup" Element peer.addAttribute("region", region);
Element country = countryLookup.exportToXML();
String city = (host.getCity() != null) ? host.getCity() : "--";
DefaultDocument document = new DefaultDocument(new DefaultElement("gnp")); peer.addAttribute("city", city);
document.getRootElement().add(groups);
document.getRootElement().add(peers); String isp = (host.getISP() != null) ? host.getISP() : "--";
document.getRootElement().add(pingEr); peer.addAttribute("isp", isp);
document.getRootElement().add(country);
return document; peer.addAttribute("longitude", String.valueOf(host.getLongitude()));
peer.addAttribute("latitude", String.valueOf(host.getLatitude()));
} String coordinates = (host.getGnpPositionReference() != null) ? host.getGnpPositionReference().getCoordinateString() : "0";
peer.addAttribute("coordinates", coordinates);
public void insertIntoRelationalDB(NetMeasurementDB db) { peers.add(peer);
}
Map<Host, NetMeasurementDB.Host> hostsScanned = new HashMap<Host, NetMeasurementDB.Host>();
// "PingErLookup" Elements
for (String group : this.groups.keySet()) { Element pingEr = pingErLookup.exportToXML();
Set<Host> hosts = this.groups.get(group); // "CountryLookup" Element
Element country = countryLookup.exportToXML();
List<NetMeasurementDB.Host> dbHosts = new ArrayList<NetMeasurementDB.Host>(hosts.size());
DefaultDocument document = new DefaultDocument(new DefaultElement("gnp"));
for (Host h : hosts) { document.getRootElement().add(groups);
document.getRootElement().add(peers);
NetMeasurementDB.Host host = hostsScanned.get(h); document.getRootElement().add(pingEr);
document.getRootElement().add(country);
if (host == null) { return document;
String countryStr = h.getCountryName(); }
String pingErRegionStr = countryLookup.getPingErRegionName(countryStr);
assert pingErRegionStr != null : "No PingEr region found for country " + countryStr; public void insertIntoRelationalDB(NetMeasurementDB db) {
City city = getCity(db, h.getCity(), h.getRegion(), countryStr, h.getCountryCode(), h.getArea(), pingErRegionStr);
Map<Host, NetMeasurementDB.Host> hostsScanned = new HashMap<Host, NetMeasurementDB.Host>();
GnpPosition pos = h.getGnpPositionReference();
List<Double> gnpCoords; for (String group : this.groups.keySet()) {
if (pos != null) {
int dims = pos.getNoOfDimensions(); Set<Host> hosts = this.groups.get(group);
gnpCoords = new ArrayList<Double>(dims);
for (int i= 0; i<dims; i++) gnpCoords.add(pos.getGnpCoordinates(i)); List<NetMeasurementDB.Host> dbHosts = new ArrayList<NetMeasurementDB.Host>(hosts.size());
} else {
gnpCoords = Collections.emptyList(); for (Host h : hosts) {
}
host = db.new Host(h.getIpAddress(), city, h.getLatitude(), h.getLongitude(), gnpCoords); NetMeasurementDB.Host host = hostsScanned.get(h);
hostsScanned.put(h, host);
} if (host == null) {
dbHosts.add(host); String countryStr = h.getCountryName();
String pingErRegionStr = countryLookup.getPingErRegionName(countryStr);
} assert pingErRegionStr != null : "No PingEr region found for country " + countryStr;
City city = getCity(db, h.getCity(), h.getRegion(), countryStr, h.getCountryCode(), h.getArea(), pingErRegionStr);
db.new Group(group, dbHosts);
GnpPosition pos = h.getGnpPositionReference();
} List<Double> gnpCoords;
if (pos != null) {
pingErLookup.insertIntoRelationalDB(db); int dims = pos.getNoOfDimensions();
} gnpCoords = new ArrayList<Double>(dims);
for (int i= 0; i<dims; i++) gnpCoords.add(pos.getGnpCoordinates(i));
public static City getCity(NetMeasurementDB db, String cityStr, String regionStr, String countryStr, String countryCode, String continentStr, String pingErRgName) { } else {
//the host never occured in a group before. Putting it into the DB. gnpCoords = Collections.emptyList();
//FIXME: some cities or regions occur multiple times but in different regions/countries, we will have to separate them! Infers problem of DB structure. }
City city = db.getStringAddrObjFromStr(City.class, cityStr); host = db.new Host(h.getIpAddress(), city, h.getLatitude(), h.getLongitude(), gnpCoords);
if (city == null) { hostsScanned.put(h, host);
Region region = db.getStringAddrObjFromStr(Region.class, regionStr); }
if (region == null) {
Country country = db.getStringAddrObjFromStr(Country.class, countryStr); dbHosts.add(host);
if (country == null) {
Continent continent = db.getStringAddrObjFromStr(Continent.class, continentStr); }
if (continent == null) continent = db.new Continent(continentStr);
db.new Group(group, dbHosts);
PingErRegion pErRegion = db.getStringAddrObjFromStr(PingErRegion.class, pingErRgName);
if (pErRegion == null) pErRegion = db.new PingErRegion(pingErRgName); }
country = db.new Country(countryStr, continent, pErRegion, countryCode);
} pingErLookup.insertIntoRelationalDB(db);
region = db.new Region(regionStr, country); }
}
city = db.new City(cityStr, region); public static City getCity(NetMeasurementDB db, String cityStr, String regionStr, String countryStr, String countryCode, String continentStr, String pingErRgName) {
} //the host never occured in a group before. Putting it into the DB.
return city; //FIXME: some cities or regions occur multiple times but in different regions/countries, we will have to separate them! Infers problem of DB structure.
} City city = db.getStringAddrObjFromStr(City.class, cityStr);
if (city == null) {
/** Region region = db.getStringAddrObjFromStr(Region.class, regionStr);
* Comparator implementation for sorting of Host with the geographical if (region == null) {
* distance to a given position Country country = db.getStringAddrObjFromStr(Country.class, countryStr);
*/ if (country == null) {
private class PeerComparatorDistance implements Comparator<Host> { Continent continent = db.getStringAddrObjFromStr(Continent.class, continentStr);
if (continent == null) continent = db.new Continent(continentStr);
double latitude;
PingErRegion pErRegion = db.getStringAddrObjFromStr(PingErRegion.class, pingErRgName);
double longitude; if (pErRegion == null) pErRegion = db.new PingErRegion(pingErRgName);
country = db.new Country(countryStr, continent, pErRegion, countryCode);
public void setPosition(double latitude, double longitude) { }
this.latitude = latitude; region = db.new Region(regionStr, country);
this.longitude = longitude; }
} city = db.new City(cityStr, region);
}
public int compare(Host peer1, Host peer2) { return city;
double distance1 = HostMap.getGeographicalDistance(peer1.getLatitude(), peer1.getLongitude(), latitude, longitude); }
double distance2 = HostMap.getGeographicalDistance(peer2.getLatitude(), peer2.getLongitude(), latitude, longitude);
if (distance1 < distance2) /**
return -1; * Comparator implementation for sorting of Host with the geographical
else if (distance1 > distance2) * distance to a given position
return 1; */
else private class PeerComparatorDistance implements Comparator<Host> {
return 0;
} double latitude;
}
double longitude;
/**
* Comparator implementation for sorting of Host with the number of measured public void setPosition(double latitude, double longitude) {
* RTTs per Host. this.latitude = latitude;
*/ this.longitude = longitude;
private class PeerComparatorNoOfConnections implements Comparator<Host> { }
public int compare(Host peer1, Host peer2) {
int coonections1 = peer1.getMeasuredMonitors().size(); public int compare(Host peer1, Host peer2) {
int coonections2 = peer2.getMeasuredMonitors().size(); double distance1 = HostMap.getGeographicalDistance(peer1.getLatitude(), peer1.getLongitude(), latitude, longitude);
if (coonections1 < coonections2) double distance2 = HostMap.getGeographicalDistance(peer2.getLatitude(), peer2.getLongitude(), latitude, longitude);
return 1; if (distance1 < distance2)
else if (coonections1 > coonections2) return -1;
return -1; else if (distance1 > distance2)
else return 1;
return 0; else
} return 0;
} }
} }
/**
* Comparator implementation for sorting of Host with the number of measured
* RTTs per Host.
*/
private class PeerComparatorNoOfConnections implements Comparator<Host> {
public int compare(Host peer1, Host peer2) {
int coonections1 = peer1.getMeasuredMonitors().size();
int coonections2 = peer2.getMeasuredMonitors().size();
if (coonections1 < coonections2)
return 1;
else if (coonections1 > coonections2)
return -1;
else
return 0;
}
}
}
...@@ -23,7 +23,6 @@ package de.tud.kom.p2psim.impl.network.modular; ...@@ -23,7 +23,6 @@ package de.tud.kom.p2psim.impl.network.modular;
import java.util.Collection; import java.util.Collection;
import de.tud.kom.p2psim.api.analyzer.MessageAnalyzer.Reason; import de.tud.kom.p2psim.api.analyzer.MessageAnalyzer.Reason;
import de.tud.kom.p2psim.api.common.Position;
import de.tud.kom.p2psim.api.common.SimHost; import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.network.BandwidthImpl; import de.tud.kom.p2psim.api.network.BandwidthImpl;
import de.tud.kom.p2psim.api.network.NetMessage; import de.tud.kom.p2psim.api.network.NetMessage;
...@@ -54,6 +53,7 @@ import de.tudarmstadt.maki.simonstrator.api.Monitor; ...@@ -54,6 +53,7 @@ import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.Monitor.Level; import de.tudarmstadt.maki.simonstrator.api.Monitor.Level;
import de.tudarmstadt.maki.simonstrator.api.component.network.Bandwidth; import de.tudarmstadt.maki.simonstrator.api.component.network.Bandwidth;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetID; import de.tudarmstadt.maki.simonstrator.api.component.network.NetID;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
/** /**
* <p> * <p>
...@@ -113,7 +113,8 @@ public class ModularNetLayer extends AbstractNetLayer { ...@@ -113,7 +113,8 @@ public class ModularNetLayer extends AbstractNetLayer {
* Device-Type of this Host * Device-Type of this Host
*/ */
ModularNetLayer(SimHost host, AbstractModularSubnet subnet, ModularNetLayer(SimHost host, AbstractModularSubnet subnet,
BandwidthImpl maxBW, NetMeasurementDB.Host hostMeta, Position position, BandwidthImpl maxBW, NetMeasurementDB.Host hostMeta,
Location position,
IPv4NetID id) { IPv4NetID id) {
super(host, id, maxBW, position, hostMeta); super(host, id, maxBW, position, hostMeta);
this.subnet = subnet; this.subnet = subnet;
......
...@@ -21,9 +21,9 @@ ...@@ -21,9 +21,9 @@
package de.tud.kom.p2psim.impl.network.modular.st; package de.tud.kom.p2psim.impl.network.modular.st;
import de.tud.kom.p2psim.api.common.Position;
import de.tud.kom.p2psim.api.common.SimHost; import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.impl.network.modular.db.NetMeasurementDB; import de.tud.kom.p2psim.impl.network.modular.db.NetMeasurementDB;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
/** /**
* This strategy determines an abstract network position of a given host * This strategy determines an abstract network position of a given host
...@@ -43,7 +43,7 @@ public interface PositioningStrategy extends ModNetLayerStrategy { ...@@ -43,7 +43,7 @@ public interface PositioningStrategy extends ModNetLayerStrategy {
* @param hostMeta * @param hostMeta
* @return * @return
*/ */
public Position getPosition( public Location getPosition(
SimHost host, SimHost host,
NetMeasurementDB db, NetMeasurementDB db,
NetMeasurementDB.Host hostMeta); NetMeasurementDB.Host hostMeta);
......
...@@ -30,7 +30,8 @@ public class FootprintLatency implements LatencyStrategy { ...@@ -30,7 +30,8 @@ public class FootprintLatency implements LatencyStrategy {
throw new IllegalArgumentException("FootprintLatency is incompatible with the NetMeasurementDB"); throw new IllegalArgumentException("FootprintLatency is incompatible with the NetMeasurementDB");
} }
double distance = nlSender.getNetPosition().getDistance(nlReceiver.getNetPosition()); double distance = nlSender.getNetPosition()
.distanceTo(nlReceiver.getNetPosition());
return (staticPart + Math.round(geoDistFactor * distance)) return (staticPart + Math.round(geoDistFactor * distance))
* Time.MILLISECOND; * Time.MILLISECOND;
......
...@@ -19,12 +19,11 @@ ...@@ -19,12 +19,11 @@
*/ */
package de.tud.kom.p2psim.impl.network.modular.st.latency; package de.tud.kom.p2psim.impl.network.modular.st.latency;
import java.util.Random; import java.util.Random;
import de.tud.kom.p2psim.api.common.Position;
import de.tud.kom.p2psim.api.network.NetLayer; import de.tud.kom.p2psim.api.network.NetLayer;
import de.tud.kom.p2psim.api.network.NetMessage; import de.tud.kom.p2psim.api.network.NetMessage;
import de.tud.kom.p2psim.impl.network.AbstractNetLayer; import de.tud.kom.p2psim.impl.network.AbstractNetLayer;
...@@ -33,50 +32,51 @@ import de.tud.kom.p2psim.impl.network.modular.st.LatencyStrategy; ...@@ -33,50 +32,51 @@ import de.tud.kom.p2psim.impl.network.modular.st.LatencyStrategy;
import de.tud.kom.p2psim.impl.network.simple.SimpleSubnet; import de.tud.kom.p2psim.impl.network.simple.SimpleSubnet;
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.Time;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
/**
* This model is abstracting the details of the four lower OSI layers (UDP and /**
* TCP) from the end-to-end connections between peers although important network * This model is abstracting the details of the four lower OSI layers (UDP and
* characteristics, like the geographical distance between peers, the processing * TCP) from the end-to-end connections between peers although important network
* delay of intermediate systems, signal propagation, congestions, * characteristics, like the geographical distance between peers, the processing
* retransmission and packet loss are incorporated into it. The message delay is * delay of intermediate systems, signal propagation, congestions,
* calculated using the following formula: * retransmission and packet loss are incorporated into it. The message delay is
* * calculated using the following formula:
* Message delay = f * (df + dist/v) *
* * Message delay = f * (df + dist/v)
* where dist - describes the geographical distance between the start and the *
* end point of the transmission, df - represents the processing delay of the * where dist - describes the geographical distance between the start and the
* intermediate systems, v - stands for the speed of the signal propagation * end point of the transmission, df - represents the processing delay of the
* through the transmission medium, and f - is a variable part which * intermediate systems, v - stands for the speed of the signal propagation
* encapsulates the retransmission, congestion. * through the transmission medium, and f - is a variable part which
* * encapsulates the retransmission, congestion.
* @author Sebastian Kaune *
* * @author Sebastian Kaune
*/ *
*/
public class SimpleLatencyModel implements LatencyStrategy { public class SimpleLatencyModel implements LatencyStrategy {
private Random rnd = Randoms.getRandom(SimpleLatencyModel.class); private Random rnd = Randoms.getRandom(SimpleLatencyModel.class);
/** /**
* Speed in kilometer per second * Speed in kilometer per second
*/ */
private final int signalSpeed = 100000; private final int signalSpeed = 100000;
/** /**
* Earth circumference in kilometres * Earth circumference in kilometres
*/ */
private final int earth_circumference = 40000; private final int earth_circumference = 40000;
private final double relSignalSpeed; private final double relSignalSpeed;
/** /**
* Constructor * Constructor
* *
*/ */
public SimpleLatencyModel() { public SimpleLatencyModel() {
relSignalSpeed = signalSpeed * (SimpleSubnet.SUBNET_WIDTH / earth_circumference); relSignalSpeed = signalSpeed * (SimpleSubnet.SUBNET_WIDTH / earth_circumference);
} }
/** /**
* Gets the distance. * Gets the distance.
* *
...@@ -84,12 +84,12 @@ public class SimpleLatencyModel implements LatencyStrategy { ...@@ -84,12 +84,12 @@ public class SimpleLatencyModel implements LatencyStrategy {
* @param receiver the receiver * @param receiver the receiver
* @return the distance * @return the distance
*/ */
public double getDistance(NetLayer sender, NetLayer receiver) { public double getDistance(NetLayer sender, NetLayer receiver) {
Position ps = sender.getNetPosition(); Location ps = sender.getNetPosition();
Position pr = receiver.getNetPosition(); Location pr = receiver.getNetPosition();
return ps.getDistance(pr); return ps.distanceTo(pr);
} }
/** /**
* Calc static delay. * Calc static delay.
* *
...@@ -97,9 +97,9 @@ public class SimpleLatencyModel implements LatencyStrategy { ...@@ -97,9 +97,9 @@ public class SimpleLatencyModel implements LatencyStrategy {
* @param distance the distance * @param distance the distance
* @return the double * @return the double
*/ */
public double calcStaticDelay(NetLayer receiver, double distance) { public double calcStaticDelay(NetLayer receiver, double distance) {
int df = Math.abs(receiver.hashCode() % 31); int df = Math.abs(receiver.hashCode() % 31);
return (df + (distance / relSignalSpeed) * 1000); return (df + (distance / relSignalSpeed) * 1000);
} }
@Override @Override
...@@ -119,6 +119,6 @@ public class SimpleLatencyModel implements LatencyStrategy { ...@@ -119,6 +119,6 @@ public class SimpleLatencyModel implements LatencyStrategy {
@Override @Override
public void writeBackToXML(BackWriter bw) { public void writeBackToXML(BackWriter bw) {
// None. // None.
} }
} }
\ No newline at end of file
...@@ -19,36 +19,36 @@ ...@@ -19,36 +19,36 @@
*/ */
package de.tud.kom.p2psim.impl.network.modular.st.latency;
import de.tud.kom.p2psim.api.common.Position; package de.tud.kom.p2psim.impl.network.modular.st.latency;
import de.tud.kom.p2psim.api.network.NetMessage; import de.tud.kom.p2psim.api.network.NetMessage;
import de.tud.kom.p2psim.impl.network.AbstractNetLayer; import de.tud.kom.p2psim.impl.network.AbstractNetLayer;
import de.tud.kom.p2psim.impl.network.modular.db.NetMeasurementDB; import de.tud.kom.p2psim.impl.network.modular.db.NetMeasurementDB;
import de.tud.kom.p2psim.impl.network.modular.st.LatencyStrategy; import de.tud.kom.p2psim.impl.network.modular.st.LatencyStrategy;
import de.tudarmstadt.maki.simonstrator.api.Time; import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
public class SimpleStaticLatencyModel implements LatencyStrategy { public class SimpleStaticLatencyModel implements LatencyStrategy {
protected long propagationDelay = 10; // 10 ms protected long propagationDelay = 10; // 10 ms
public SimpleStaticLatencyModel(long staticLatency) { public SimpleStaticLatencyModel(long staticLatency) {
this.setLatency(staticLatency); this.setLatency(staticLatency);
} }
/** /**
* Sets the static latency which is expected in millseconds. That is, if * Sets the static latency which is expected in millseconds. That is, if
* <code>staticLatency</code> is set to 10, the simulator will translate it * <code>staticLatency</code> is set to 10, the simulator will translate it
* into simulation units as follows: staticLatency * * into simulation units as follows: staticLatency *
* Simulator.MILLISECOND_UNIT. * Simulator.MILLISECOND_UNIT.
* *
* @param staticLatency * @param staticLatency
* the static latency in milliseconds. * the static latency in milliseconds.
*/ */
public void setLatency(long staticLatency) { public void setLatency(long staticLatency) {
this.propagationDelay = staticLatency; this.propagationDelay = staticLatency;
} }
/** /**
...@@ -60,13 +60,13 @@ public class SimpleStaticLatencyModel implements LatencyStrategy { ...@@ -60,13 +60,13 @@ public class SimpleStaticLatencyModel implements LatencyStrategy {
*/ */
protected double getDistance(AbstractNetLayer nlSender, AbstractNetLayer nlReceiver){ protected double getDistance(AbstractNetLayer nlSender, AbstractNetLayer nlReceiver){
Position ps = nlSender.getNetPosition(); Location ps = nlSender.getNetPosition();
Position pr = nlReceiver.getNetPosition(); Location pr = nlReceiver.getNetPosition();
return ps.getDistance(pr); return ps.distanceTo(pr);
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see de.tud.kom.p2psim.impl.network.modular.st.LatencyStrategy#getMessagePropagationDelay(de.tud.kom.p2psim.api.network.NetMessage, de.tud.kom.p2psim.impl.network.AbstractNetLayer, de.tud.kom.p2psim.impl.network.AbstractNetLayer, de.tud.kom.p2psim.impl.network.modular.db.NetMeasurementDB) * @see de.tud.kom.p2psim.impl.network.modular.st.LatencyStrategy#getMessagePropagationDelay(de.tud.kom.p2psim.api.network.NetMessage, de.tud.kom.p2psim.impl.network.AbstractNetLayer, de.tud.kom.p2psim.impl.network.AbstractNetLayer, de.tud.kom.p2psim.impl.network.modular.db.NetMeasurementDB)
...@@ -85,6 +85,6 @@ public class SimpleStaticLatencyModel implements LatencyStrategy { ...@@ -85,6 +85,6 @@ public class SimpleStaticLatencyModel implements LatencyStrategy {
@Override @Override
public void writeBackToXML(BackWriter bw) { public void writeBackToXML(BackWriter bw) {
bw.writeTime("propagationDelay", propagationDelay); bw.writeTime("propagationDelay", propagationDelay);
} }
} }
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