Commit 461c056b authored by Nils Richerzhagen's avatar Nils Richerzhagen
Browse files

Merge branch 'master' into 'nr/master-debug'

Merge Master into nr/master-debug



See merge request !23
parents 9b550db0 88fe42d9
......@@ -72,18 +72,18 @@ public interface Link {
public double getDropProbability();
/**
* Bandwidth we can assume on this link in byte/s - we use this bandwidth
* and calculate the real number of bytes that we need to transmit,
* including redundancy and retransmits, to get the actual bandwidth visible
* to the user.
* Bandwidth we can assume on this link in bit/s - we use this bandwidth and
* calculate the real number of bytes that we need to transmit, including
* redundancy and retransmits, to get the actual bandwidth visible to the
* user.
*
* <b>This is in byte/s</b>
* <b>This is in bit/s</b>
*
* @param isBroadcast
* for a broadcast the BW might be slower, as a more robust
* scheme might be used
*
* @return BW in byte/s
* @return BW in bit/s as defined in Rate (api)
*/
public long getBandwidth(boolean isBroadcast);
......
......@@ -22,6 +22,7 @@ package de.tud.kom.p2psim.api.linklayer.mac;
import de.tud.kom.p2psim.api.linklayer.LinkLayer;
import de.tud.kom.p2psim.impl.simengine.Simulator;
import de.tudarmstadt.maki.simonstrator.api.Rate;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetworkComponent.NetInterfaceName;
......@@ -48,7 +49,7 @@ public enum PhyType {
* (LinkLayer might add retransmission behavior as in 802.11), 5MBit/s netto
* (802.11b) BW, 500us latency, 2,2kB MTU, Broadcast
*/
WIFI(NetInterfaceName.WIFI, 0.01, 758000 / 8, 500 * Time.MICROSECOND,
WIFI(NetInterfaceName.WIFI, 0.01, 5 * Rate.Mbit_s, 500 * Time.MICROSECOND,
2334, true),
/**
* A wired connection based on a TopologyView
......@@ -56,7 +57,7 @@ public enum PhyType {
* Assuming the following defaults: 0.1% link-layer loss, 100 Mbit/s, 1ms
* Link-Latency, 1,5kB MTU
*/
ETHERNET(NetInterfaceName.ETHERNET, 0.001, 100000000 / 8,
ETHERNET(NetInterfaceName.ETHERNET, 0.001, 100 * Rate.Mbit_s,
1 * Time.MILLISECOND, 1500, false),
/**
......@@ -66,7 +67,7 @@ public enum PhyType {
* Assuming the following defaults: zero link-layer packet loss due to
* scheduling, 384kBit/s, 500us latency, 1,4 kByte MTU
*/
UMTS(NetInterfaceName.MOBILE, 0, 384000 / 8,
UMTS(NetInterfaceName.MOBILE, 0, 384 * Rate.kbit_s,
500 * Simulator.MICROSECOND_UNIT, 1472, false),
/**
......@@ -76,14 +77,14 @@ public enum PhyType {
* Assuming the following defaults: zero link-layer packet loss, 3Mbit/s BW,
* 500us latency, 1kByte MTU
*/
BLUETOOTH(NetInterfaceName.BLUETOOTH, 0.0, 3000000 / 8,
BLUETOOTH(NetInterfaceName.BLUETOOTH, 0.0, 3 * Rate.Mbit_s,
500 * Simulator.MICROSECOND_UNIT, 1024, true);
private double defaultDropProbability;
/**
* Default bw of a link in this PHY (a link is unidirectional, therefore
* this is just one value) in byte/s
* this is just one value) in bit/s
*/
private long defaultRawBW;
......@@ -103,7 +104,7 @@ public enum PhyType {
*
* @param defaultDropProbability
* @param defaultRawBW
* bw in byte/s
* bw in bit/s
* @param defaultLatency
* @param defaultMTU
*/
......@@ -131,7 +132,7 @@ public enum PhyType {
}
/**
* The Default BW of a link (unidirectional) in byte/s
* The Default BW of a link (unidirectional) in bit/s
*
* @return
*/
......
......@@ -26,56 +26,60 @@ import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor;
public class BandwidthImpl implements Bandwidth, Cloneable {
private double downBW;
private long downBW;
private double upBW;
private long upBW;
@XMLConfigurableConstructor({ "downUpBW" })
public BandwidthImpl(double downUpBW) {
public BandwidthImpl(long downUpBW) {
this(downUpBW, downUpBW);
}
@XMLConfigurableConstructor({ "downBW", "upBW" })
public BandwidthImpl(double downBW, double upBW) {
public BandwidthImpl(long downBW, long upBW) {
super();
this.downBW = downBW;
this.upBW = upBW;
}
/**
* The downstream bandwidth in byte/s
* @return
/**
* The downstream bandwidth in bit/s
*
* @return
*/
public double getDownBW() {
public long getDownBW() {
return downBW;
}
/**
* The upstream bandwidth in byte/s
* @return
/**
* The upstream bandwidth in bit/s
*
* @return
*/
public double getUpBW() {
public long getUpBW() {
return upBW;
}
/**
* Sets the downstream bandwidth in byte/s
* @param downBW
/**
* Sets the downstream bandwidth in bit/s
*
* @param downBW
*/
public void setDownBW(double downBW) {
public void setDownBW(long downBW) {
this.downBW = downBW;
}
/**
* Sets the upstream bandwidth in byte/s
* @param upBW
/**
* Sets the upstream bandwidth in bit/s
*
* @param upBW
*/
public void setUpBW(double upBW) {
public void setUpBW(long upBW) {
this.upBW = upBW;
}
public String toString() {
return "(Down: " + downBW + " byte/s, Up: " + upBW + " byte/s)";
return "(Down: " + downBW + " bit/s, Up: " + upBW + " bit/s)";
}
public BandwidthImpl clone() {
......@@ -87,9 +91,9 @@ public class BandwidthImpl implements Bandwidth, Cloneable {
final int prime = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(downBW);
temp = downBW;
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(upBW);
temp = upBW;
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
......@@ -103,11 +107,9 @@ public class BandwidthImpl implements Bandwidth, Cloneable {
if (getClass() != obj.getClass())
return false;
BandwidthImpl other = (BandwidthImpl) obj;
if (Double.doubleToLongBits(downBW) != Double
.doubleToLongBits(other.downBW))
if (downBW != other.downBW)
return false;
if (Double.doubleToLongBits(upBW) != Double
.doubleToLongBits(other.upBW))
if (upBW != other.upBW)
return false;
return true;
}
......
......@@ -134,4 +134,13 @@ public interface TopologyView
*/
public double getDistance(MacAddress addressA, MacAddress addressB);
/**
* Denotes whether this {@link TopologyView} has a real link layer (i.e.,
* hosts within this view act as Layer 2 elements, connected by a layer 2
* link). In "Internet-wide" topology views, this is usually NOT the case.
*
* @return
*/
public boolean hasRealLinkLayer();
}
......@@ -572,7 +572,7 @@ public abstract class AbstractMacLayer implements MacLayer {
* We have no neighbors!
*/
eventInfo.arrivedAt(this, true);
timeToSend = 1 * Time.MILLISECOND;
timeToSend = 1 * Time.MICROSECOND;
}
return timeToSend;
}
......@@ -767,8 +767,9 @@ public abstract class AbstractMacLayer implements MacLayer {
* @return
*/
protected long getUploadTime(Message msg, Link l, boolean isBroadcast) {
// Size is in byte, bandwidth in bit/s
long uploadTime = Math.max(
msg.getSize() * Time.SECOND / l.getBandwidth(isBroadcast),
msg.getSize() * 8 * Time.SECOND / l.getBandwidth(isBroadcast),
Time.MICROSECOND);
assert uploadTime > 0;
return uploadTime;
......
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.linklayer.mac;
import de.tud.kom.p2psim.api.common.SimHost;
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.PhyType;
import de.tud.kom.p2psim.api.network.BandwidthImpl;
import de.tudarmstadt.maki.simonstrator.api.Message;
/**
* This MAC provides an outgoing queue and schedules messages in a shared
* Medium. It is ensured that no MAC sends while another MAC within range is
* sending. Of course, this only makes sense in a Broadcast-Medium.
*
* @author Bjoern Richerzhagen
* @version 1.0, 27.03.2012
*/
public class CollisionAwareMac extends EnqueuingMac {
/**
* Create a new MAC for a broadcast-medium that avoids collisions
*
* @param ownMacAddress
* @param phy
* @param maxQueueLength
* @param maxTimeInQueue
* @param maxRetransmissions
* @param bandwidth
* the maximum BW of this MAC (i.e. the BW that would be achieved
* if messages are not queued)
*/
public CollisionAwareMac(SimHost host, MacAddress ownMacAddress,
PhyType phy,
int maxQueueLength, long maxTimeInQueue, int maxRetransmissions,
BandwidthImpl bandwidth) {
super(host, ownMacAddress, phy, maxQueueLength, maxTimeInQueue,
maxRetransmissions, bandwidth);
if (!phy.isBroadcastMedium()) {
throw new AssertionError(
"The CollisionAwareMac requires a Broadcast-PHY such as WIFI or BLUETOOTH");
}
}
/*
*
* TODO
*/
/**
* The EventInfo-Object that is used by this MAC to track blocking of MACs
*
* @author Bjoern Richerzhagen
* @version 1.0, 27.03.2012
*/
protected class CollisionAwareMacEventInfo extends
DefaultMacEventInformation {
public CollisionAwareMacEventInfo(Message msg, EnqueuingMac sender,
MacAddress receiver, long timeInQueue) {
super(msg, sender.getMacAddress(), receiver, timeInQueue);
}
@Override
public void arrivedAt(MacLayer receiver, boolean wasDropped) {
super.arrivedAt(receiver, wasDropped);
}
}
}
......@@ -29,7 +29,6 @@ import de.tud.kom.p2psim.api.linklayer.mac.PhyType;
import de.tud.kom.p2psim.api.network.BandwidthImpl;
import de.tud.kom.p2psim.api.scenario.ConfigurationException;
import de.tud.kom.p2psim.impl.linklayer.DefaultLinkMessageEvent;
import de.tud.kom.p2psim.impl.topology.views.CloudTopologyView;
import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.Time;
......@@ -53,8 +52,11 @@ public class EnqueuingMac extends AbstractMacLayer {
private long nextRcvTime = 0;
/**
* This will simulate the incoming queue at the receiver as well. Does only
* make sense in a scenario where there is no
* This will simulate the incoming queue at the receiver as well. This does
* only make sense in topologyViews that consider real link layers (e.g.,
* Wi-Fi). For all Internet-scale scenarios, where we use links as a concept
* for a connection between end hosts and not in the sense of a real link
* layer, this HAS TO BE false.
*/
private boolean simulateReceiverQueue = true;
......@@ -82,15 +84,7 @@ public class EnqueuingMac extends AbstractMacLayer {
@Override
public void initialize() throws ConfigurationException {
super.initialize();
if (getTopologyView() instanceof CloudTopologyView) {
/*
* In this case, we do not have a "real" Linklayer, i.e. messages
* will travel over multiple hops that are not simulated. Therefore,
* we do not wait until the message can be received by the other
* MAC, before we send the next one.
*/
simulateReceiverQueue = false;
}
this.simulateReceiverQueue = getTopologyView().hasRealLinkLayer();
}
@Override
......
......@@ -25,6 +25,7 @@ import de.tud.kom.p2psim.api.network.BandwidthDetermination;
import de.tud.kom.p2psim.api.network.BandwidthImpl;
import de.tud.kom.p2psim.impl.network.modular.db.NetMeasurementDB;
import de.tud.kom.p2psim.impl.util.BackToXMLWritable;
import de.tudarmstadt.maki.simonstrator.api.Rate;
import de.tudarmstadt.maki.simonstrator.api.component.HostComponentFactory;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetID;
......@@ -81,19 +82,19 @@ public abstract class AbstractNetLayerFactory implements HostComponentFactory,
this.bandwidthDetermination = bandwidthDetermination;
}
/**
* Sets the downstream bandwidth in bytes/sec
*
* @param downBandwidth
/**
* Sets the downstream bandwidth in bit/sec, use {@link Rate}
*
* @param downBandwidth
*/
public void setDownBandwidth(long downBandwidth) {
this.downBandwidth = downBandwidth;
}
/**
* Sets the upstream bandwidth in bytes/sec
*
* @param upBandwidth
/**
* Sets the upstream bandwidth in bit/sec, use {@link Rate}
*
* @param upBandwidth
*/
public void setUpBandwidth(long upBandwidth) {
this.upBandwidth = upBandwidth;
......
......@@ -130,9 +130,9 @@ public class BandwidthEstimator {
inLastEditInSec = currentTimeInSec;
if (isFreeBandwidth) {
estimatedBandwidth.setDownBW(Math.max(0, maxBandwidth.getDownBW()
- inTransBytes / inTransRing.length));
- inTransBytes * 8 / inTransRing.length));
} else {
estimatedBandwidth.setDownBW(inTransBytes / inTransRing.length);
estimatedBandwidth.setDownBW(inTransBytes * 8 / inTransRing.length);
}
}
......@@ -150,9 +150,9 @@ public class BandwidthEstimator {
outLastEditInSec = currentTimeInSec;
if (isFreeBandwidth) {
estimatedBandwidth.setUpBW(Math.max(0, maxBandwidth.getUpBW()
- outTransBytes / outTransRing.length));
- outTransBytes * 8 / outTransRing.length));
} else {
estimatedBandwidth.setUpBW(outTransBytes / outTransRing.length);
estimatedBandwidth.setUpBW(outTransBytes * 8 / outTransRing.length);
}
}
......@@ -181,9 +181,10 @@ public class BandwidthEstimator {
}
if (isFreeBandwidth) {
estimatedBandwidth.setUpBW(Math.max(0, maxBandwidth.getUpBW()
- outTransBytes / outTransRing.length));
- outTransBytes * 8 / outTransRing.length));
} else {
estimatedBandwidth.setUpBW(outTransBytes / outTransRing.length);
estimatedBandwidth
.setUpBW(outTransBytes * 8 / outTransRing.length);
}
}
if (currentTimeInSec > inLastEditInSec) {
......@@ -204,11 +205,13 @@ public class BandwidthEstimator {
}
}
if (isFreeBandwidth) {
estimatedBandwidth.setDownBW(Math.max(0,
maxBandwidth.getDownBW() - inTransBytes
estimatedBandwidth
.setDownBW(Math.max(0, maxBandwidth.getDownBW()
- inTransBytes * 8
/ inTransRing.length));
} else {
estimatedBandwidth.setDownBW(inTransBytes / inTransRing.length);
estimatedBandwidth
.setDownBW(inTransBytes * 8 / inTransRing.length);
}
}
}
......
......@@ -22,25 +22,24 @@
package de.tud.kom.p2psim.impl.network.bandwidthDetermination;
/**
* The implemented bandwidth distribution is taken from the latest OECD
* broadband report (For further information, please see Oecd broadband portal,
* http://www.oecd.org/sti/ict/broadband). The provided values for upload- and
* download-bandwidth are denoted in bytes per second.
*
* @author Leo Nobach (additional changes: Dominik Stingl)
*
/**
* The implemented bandwidth distribution is taken from the latest OECD
* broadband report (For further information, please see Oecd broadband portal,
* http://www.oecd.org/sti/ict/broadband). Values are provided in bit/s
*
* @author Leo Nobach (additional changes: Dominik Stingl)
*
*/
public class OECDReportBandwidthDetermination extends PickFromRandomGroupBandwidthDetermination {
@Override
public void addBandwidthGroups() {
addNewBandwidth(7000, 7000, 600); // Modem 15%
addNewBandwidth(8000, 8000, 600); // ISDN
addNewBandwidth(87355, 1202843, 1601); // DSL 41%
addNewBandwidth(89000, 236111, 47); // Wireless 1%
addNewBandwidth(158001, 1856966, 758); // Cable 19%
addNewBandwidth(4280818, 8165793, 258); // FTTx 6%
addNewBandwidth(7000 * 8, 7000 * 8, 600); // Modem 15%
addNewBandwidth(8000 * 8, 8000 * 8, 600); // ISDN
addNewBandwidth(87355 * 8, 1202843 * 8, 1601); // DSL 41%
addNewBandwidth(89000 * 8, 236111 * 8, 47); // Wireless 1%
addNewBandwidth(158001 * 8, 1856966 * 8, 758); // Cable 19%
addNewBandwidth(4280818 * 8, 8165793 * 8, 258); // FTTx 6%
// 3864
}
......
......@@ -54,19 +54,19 @@ public abstract class PickFromRandomGroupBandwidthDetermination implements
public abstract void addBandwidthGroups();
/**
* Adds a new type of a network interface to the collection of different
* network interfaces. The specification for a new type consists of the
* upload- and download-bandwidth as well as of the relative usage-amount of
* the network interface
*
* @param upBW
* describes the maximum upload-bandwidth in byte per second
* @param downBW
* describes the maximum download-bandwidth in byte per second
* @param part
* describes the proportion of network interfaces of the given
* type
/**
* Adds a new type of a network interface to the collection of different
* network interfaces. The specification for a new type consists of the
* upload- and download-bandwidth as well as of the relative usage-amount of
* the network interface
*
* @param upBW
* describes the maximum upload-bandwidth in bit per second
* @param downBW
* describes the maximum download-bandwidth in bit per second
* @param part
* describes the proportion of network interfaces of the given
* type
*/
protected void addNewBandwidth(long upBW, long downBW, int part) {
distributionMax += part;
......
......@@ -38,9 +38,9 @@ import de.tudarmstadt.maki.simonstrator.api.Randoms;
public class RandomizedBandwidthDetermination implements
BandwidthDetermination<Integer> {
private double maxDownBandwidth = 10000d;
private long maxDownBandwidth = 10000;
private double minDownBandwidth = 5000d;
private long minDownBandwidth = 5000;
private double upstreamBWQuota = 0.1;
......@@ -61,11 +61,11 @@ public class RandomizedBandwidthDetermination implements
return new BandwidthImpl((long)Math.floor(downBandwidth), (long)Math.floor(upBandwidth));
}
public void setMaxDownBandwidth(double maxDownBandwidth) {
public void setMaxDownBandwidth(long maxDownBandwidth) {
this.maxDownBandwidth = maxDownBandwidth;
}
public void setMinDownBandwidth(double minDownBandwidth) {
public void setMinDownBandwidth(long minDownBandwidth) {
this.minDownBandwidth = minDownBandwidth;
}
......
......@@ -319,16 +319,17 @@ public class DirectedGraph {
while (!this.getAllFlows().isEmpty()) {
/* Line 4 + 5. */
double fairshare_rate_upload = Double.MAX_VALUE;
double fairshare_rate_download = Double.MAX_VALUE;
long fairshare_rate_upload = Long.MAX_VALUE;
long fairshare_rate_download = Long.MAX_VALUE;
for (final FairshareNode node : this.getAllNodes()) {
/* Calculate UPLOADING c_i / |F_i| */
final double c_i_up = node.getCurrentBandwidth().getUpBW();
final long c_i_up = node.getCurrentBandwidth().getUpBW();
if (c_i_up > 0) {
final int outgoing_links = this.getUploadingFlowsFrom(node).size();
final double current_fairshare_rate = (outgoing_links > 0) ? c_i_up / outgoing_links : Double.MAX_VALUE;
final long current_fairshare_rate = (outgoing_links > 0)
? c_i_up / outgoing_links : Long.MAX_VALUE;
/* Add to minimal set. */
if (current_fairshare_rate <= fairshare_rate_upload) {
......@@ -344,11 +345,12 @@ public class DirectedGraph {
}
/* Calculate DOWNLOADING c_i / |F_i| */
final double c_i_down = node.getCurrentBandwidth().getDownBW();
final long c_i_down = node.getCurrentBandwidth().getDownBW();
if (c_i_down > 0) {
final int outgoing_links = this.getDownloadingFlowsTo(node).size();
final double current_fairshare_rate = (outgoing_links > 0) ? c_i_down / outgoing_links : Double.MAX_VALUE;
final long current_fairshare_rate = (outgoing_links > 0)
? c_i_down / outgoing_links : Long.MAX_VALUE;
/* Add to minimal set. */
if (current_fairshare_rate <= fairshare_rate_download) {
......@@ -366,7 +368,8 @@ public class DirectedGraph {
}
/* Line 6 - 10. */
final double fairshare_rate = fairshare_rate_upload > fairshare_rate_download ? fairshare_rate_download : fairshare_rate_upload;
final long fairshare_rate = fairshare_rate_upload > fairshare_rate_download
? fairshare_rate_download : fairshare_rate_upload;
if (fairshare_rate_upload > fairshare_rate_download) {
satUp.clear();
} else if (fairshare_rate_upload < fairshare_rate_download) {
......
......@@ -17,7 +17,7 @@ public class FairshareFlow implements Comparable<FairshareFlow> {
private final long propagationDelay;
/** The current rate. */
private double currentRate;
private long currentRate;
/** Time when transfer is expected to end. */
private long transferEndTime;
......@@ -166,7 +166,7 @@ public class FairshareFlow implements Comparable<FairshareFlow> {
* @throws Exception
* thrown if not enough bandwidth could be reserved
*/
public long setRate(double newRate) throws Exception {
public long setRate(long newRate) throws Exception {
assert( newRate >= 0 );
......@@ -281,7 +281,7 @@ public class FairshareFlow implements Comparable<FairshareFlow> {
if( this.getRate() == 0 ) {
time = Double.POSITIVE_INFINITY;
} else {
time = this.remainingBytes / this.getRate();
time = this.remainingBytes * 8 / this.getRate();
}
this.transferEndTime = Math.round(time * Time.SECOND) + currentTime;
......
package de.tud.kom.p2psim.impl.network.fairshareng;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import de.tud.kom.p2psim.api.analyzer.MessageAnalyzer.Reason;
import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.network.BandwidthImpl;
import de.tud.kom.p2psim.api.network.FlowBasedNetlayer;
import de.tud.kom.p2psim.api.network.NetMessage;
import de.tud.kom.p2psim.api.network.NetProtocol;
import de.tud.kom.p2psim.api.transport.TransProtocol;
import de.tud.kom.p2psim.impl.network.AbstractNetLayer;
import de.tud.kom.p2psim.impl.network.IPv4Message;
import de.tud.kom.p2psim.impl.network.modular.db.NetMeasurementDB;
import de.tud.kom.p2psim.impl.transport.AbstractTransMessage;
import de.tudarmstadt.maki.simonstrator.api.Message;
import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.Monitor.Level;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetID;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
/**
* The Class Node.
*/
public class FairshareNode extends AbstractNetLayer implements
FlowBasedNetlayer {
/** The subnet. */
private final FairshareSubnet subnet;
/** The host queues. */
private final Map<FairshareNode, LinkedList<NetMessage>> hostQueues;
/** The Constant FLOAT_DELTA to correct Floats 9.999 to 10. */
private final static float FLOAT_DELTA = 1e-7f;
/** The hash code. */
private final int hashCode;
/**
* Instantiates a new node.
* @param netID
* @param geoLoc
*/
public FairshareNode(SimHost host, FairshareSubnet subnet, NetID netID,
BandwidthImpl maxBandwidth, Location position,
NetMeasurementDB.Host hostMeta) {
super(host, netID, maxBandwidth, position, hostMeta);
this.subnet = subnet;
this.hostQueues = new LinkedHashMap<FairshareNode, LinkedList<NetMessage>>();
this.hashCode = this.getNetID().hashCode();
}
/**
* Adds rate to the current down rate.
*
* @param downRate
*
* the down rate
* @throws Exception
* the exception
*/
public void addCurrentDownRate(double downRate) throws Exception {
final double currentDownBW = this.getCurrentBandwidth().getDownBW();
double realDownRate = currentDownBW - downRate;
/* Fix float, in case we get 9.999 save 10. */
if( Math.abs(Math.round(realDownRate) - realDownRate) < FLOAT_DELTA ) {
realDownRate = Math.round(realDownRate);
}
this.getCurrentBandwidth().setDownBW(realDownRate);
}
/**
* Adds rate to the current up rate.
*
* @param upRate
* the up rate
* @throws Exception
* the exception
*/
public void addCurrentUpRate(double upRate) throws Exception {
final double currentUpBW = this.getCurrentBandwidth().getUpBW();
double realUpRate = currentUpBW - upRate;
/* Fix float, in case we get 9.999 save 10. */
if( Math.abs(Math.round(realUpRate) - realUpRate) < FLOAT_DELTA ) {
realUpRate = Math.round(realUpRate);
}
this.getCurrentBandwidth().setUpBW(realUpRate);
}
/**
* Resets the node by setting current rates to zero.
*/
public void reset() {
this.setCurrentBandwidth(this.getMaxBandwidth().clone());
}
/* (non-Javadoc)
* @see de.tud.kom.p2psim.impl.network.AbstractNetLayer#goOffline()
*/
@Override
public void goOffline() {
super.goOffline();
this.subnet.disconnectHost(this);
}
/* (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)
*/
@Override
public void send(Message msg, NetID receiverId, NetProtocol protocol) {
if (isOnline()) {
assert (msg.getSize() >= 0);
assert (isSupported(((AbstractTransMessage) msg).getProtocol()));
final NetMessage netMsg = new IPv4Message(msg, receiverId, this.getNetID());
final TransProtocol tpMsg = ((AbstractTransMessage) msg).getProtocol();
if (tpMsg.equals(TransProtocol.UDP)) {
if (hasAnalyzer) {
netAnalyzerProxy
.netMsgEvent(netMsg, getHost(), Reason.SEND);
}
this.subnet.sendUDP(netMsg);
} else if (tpMsg.equals(TransProtocol.TCP)) {
final FairshareNode receiver = this.subnet.getNetLayer(receiverId);
LinkedList<NetMessage> queuedMessages = this.hostQueues.get(receiver);
if (queuedMessages == null) {
queuedMessages = new LinkedList<NetMessage>();
this.hostQueues.put(receiver, queuedMessages);
}
if (hasAnalyzer) {
netAnalyzerProxy
.netMsgEvent(netMsg, getHost(), Reason.SEND);
}
if (queuedMessages.isEmpty()) {
try {
this.subnet.sendTCPMessage(netMsg);
} catch (final Exception e) {
/*
* Can't throw exception here as send(Message msg, NetID receiverId, NetProtocol protocol) is overwritten.
*/
Monitor.log(FairshareNode.class, Level.ERROR,
"Exception..: sendTCP failed. %s", e);
assert(false) : "sendTCP failed: " + e;
}
}
queuedMessages.add(netMsg);
} else {
/*
* Can't throw exception here as send(Message msg, NetID receiverId, NetProtocol protocol) is overwritten.
*/
Monitor.log(FairshareNode.class, Level.ERROR,
"Unsupported transport protocol " + tpMsg);
assert (false) : "Unsupported transport protocol " + tpMsg;
}
} else {
Monitor.log(FairshareNode.class, Level.WARN, "Host " + this
+ " is offline.");
}
}
/* (non-Javadoc)
* @see de.tud.kom.p2psim.impl.network.AbstractNetLayer#isSupported(de.tud.kom.p2psim.api.transport.TransProtocol)
*/
@Override
protected boolean isSupported(TransProtocol protocol) {
return (protocol.equals(TransProtocol.UDP) || protocol.equals(TransProtocol.TCP));
}
/**
* Checks if message queue is empty.
*
* @param receiver the receiver
* @return true, if is message queue empty
*/
public boolean isMessageQueueEmpty(FairshareNode receiver) {
return this.hostQueues.get(receiver).isEmpty();
}
/**
* Peek message queue and return size of next expected arrival.
*
* @param receiver the receiver
* @return the double
*/
public double peekMessageQueue(FairshareNode receiver) {
return this.hostQueues.get(receiver).get(0).getSize();
}
/**
* Gets a read-only view on message queue.
*
* @param receiver the receiver
* @return the view on message queue
*/
public List<NetMessage> getViewOnMessageQueue(FairshareNode receiver) {
return Collections.unmodifiableList(this.hostQueues.get(receiver));
}
/**
* Removes the message from queue.
*
* @param receiver the receiver
* @return the net message
*/
public NetMessage removeMessageFromQueue(FairshareNode receiver) {
return this.hostQueues.get(receiver).remove(0);
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
return (obj instanceof FairshareNode) ? ((FairshareNode) obj).getNetID().hashCode() == this.getNetID().hashCode() : super.equals(obj);
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return this.getLocalInetAddress() + " (U:"
+ this.getCurrentBandwidth().getUpBW() + "/D:"
+ this.getCurrentBandwidth().getDownBW() + ")";
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
/* Precomputed to save time. */
return this.hashCode;
}
}
package de.tud.kom.p2psim.impl.network.fairshareng;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import de.tud.kom.p2psim.api.analyzer.MessageAnalyzer.Reason;
import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.network.BandwidthImpl;
import de.tud.kom.p2psim.api.network.FlowBasedNetlayer;
import de.tud.kom.p2psim.api.network.NetMessage;
import de.tud.kom.p2psim.api.network.NetProtocol;
import de.tud.kom.p2psim.api.transport.TransProtocol;
import de.tud.kom.p2psim.impl.network.AbstractNetLayer;
import de.tud.kom.p2psim.impl.network.IPv4Message;
import de.tud.kom.p2psim.impl.network.modular.db.NetMeasurementDB;
import de.tud.kom.p2psim.impl.transport.AbstractTransMessage;
import de.tudarmstadt.maki.simonstrator.api.Message;
import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.Monitor.Level;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetID;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
/**
* The Class Node.
*/
public class FairshareNode extends AbstractNetLayer implements
FlowBasedNetlayer {
/** The subnet. */
private final FairshareSubnet subnet;
/** The host queues. */
private final Map<FairshareNode, LinkedList<NetMessage>> hostQueues;
/** The Constant FLOAT_DELTA to correct Floats 9.999 to 10. */
private final static float FLOAT_DELTA = 1e-7f;
/** The hash code. */
private final int hashCode;
/**
* Instantiates a new node.
* @param netID
* @param geoLoc
*/
public FairshareNode(SimHost host, FairshareSubnet subnet, NetID netID,
BandwidthImpl maxBandwidth, Location position,
NetMeasurementDB.Host hostMeta) {
super(host, netID, maxBandwidth, position, hostMeta);
this.subnet = subnet;
this.hostQueues = new LinkedHashMap<FairshareNode, LinkedList<NetMessage>>();
this.hashCode = this.getNetID().hashCode();
}
/**
* Adds rate to the current down rate.
*
* @param downRate
*
* the down rate
* @throws Exception
* the exception
*/
public void addCurrentDownRate(long downRate) throws Exception {
final long currentDownBW = this.getCurrentBandwidth().getDownBW();
long realDownRate = currentDownBW - downRate;
/* Fix float, in case we get 9.999 save 10. */
if( Math.abs(Math.round(realDownRate) - realDownRate) < FLOAT_DELTA ) {
realDownRate = Math.round(realDownRate);
}
this.getCurrentBandwidth().setDownBW(realDownRate);
}
/**
* Adds rate to the current up rate.
*
* @param upRate
* the up rate
* @throws Exception
* the exception
*/
public void addCurrentUpRate(long upRate) throws Exception {
final long currentUpBW = this.getCurrentBandwidth().getUpBW();
long realUpRate = currentUpBW - upRate;
/* Fix float, in case we get 9.999 save 10. */
if( Math.abs(Math.round(realUpRate) - realUpRate) < FLOAT_DELTA ) {
realUpRate = Math.round(realUpRate);
}
this.getCurrentBandwidth().setUpBW(realUpRate);
}
/**
* Resets the node by setting current rates to zero.
*/
public void reset() {
this.setCurrentBandwidth(this.getMaxBandwidth().clone());
}
/* (non-Javadoc)
* @see de.tud.kom.p2psim.impl.network.AbstractNetLayer#goOffline()
*/
@Override
public void goOffline() {
super.goOffline();
this.subnet.disconnectHost(this);
}
/* (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)
*/
@Override
public void send(Message msg, NetID receiverId, NetProtocol protocol) {
if (isOnline()) {
assert (msg.getSize() >= 0);
assert (isSupported(((AbstractTransMessage) msg).getProtocol()));
final NetMessage netMsg = new IPv4Message(msg, receiverId, this.getNetID());
final TransProtocol tpMsg = ((AbstractTransMessage) msg).getProtocol();
if (tpMsg.equals(TransProtocol.UDP)) {
if (hasAnalyzer) {
netAnalyzerProxy
.netMsgEvent(netMsg, getHost(), Reason.SEND);
}
this.subnet.sendUDP(netMsg);
} else if (tpMsg.equals(TransProtocol.TCP)) {
final FairshareNode receiver = this.subnet.getNetLayer(receiverId);
LinkedList<NetMessage> queuedMessages = this.hostQueues.get(receiver);
if (queuedMessages == null) {
queuedMessages = new LinkedList<NetMessage>();
this.hostQueues.put(receiver, queuedMessages);
}
if (hasAnalyzer) {
netAnalyzerProxy
.netMsgEvent(netMsg, getHost(), Reason.SEND);
}
if (queuedMessages.isEmpty()) {
try {
this.subnet.sendTCPMessage(netMsg);
} catch (final Exception e) {
/*
* Can't throw exception here as send(Message msg, NetID receiverId, NetProtocol protocol) is overwritten.
*/
Monitor.log(FairshareNode.class, Level.ERROR,
"Exception..: sendTCP failed. %s", e);
assert(false) : "sendTCP failed: " + e;
}
}
queuedMessages.add(netMsg);
} else {
/*
* Can't throw exception here as send(Message msg, NetID receiverId, NetProtocol protocol) is overwritten.
*/
Monitor.log(FairshareNode.class, Level.ERROR,
"Unsupported transport protocol " + tpMsg);
assert (false) : "Unsupported transport protocol " + tpMsg;
}
} else {
Monitor.log(FairshareNode.class, Level.WARN, "Host " + this
+ " is offline.");
}
}
/* (non-Javadoc)
* @see de.tud.kom.p2psim.impl.network.AbstractNetLayer#isSupported(de.tud.kom.p2psim.api.transport.TransProtocol)
*/
@Override
protected boolean isSupported(TransProtocol protocol) {
return (protocol.equals(TransProtocol.UDP) || protocol.equals(TransProtocol.TCP));
}
/**
* Checks if message queue is empty.
*
* @param receiver the receiver
* @return true, if is message queue empty
*/
public boolean isMessageQueueEmpty(FairshareNode receiver) {
return this.hostQueues.get(receiver).isEmpty();
}
/**
* Peek message queue and return size of next expected arrival.
*
* @param receiver the receiver
* @return the double
*/
public double peekMessageQueue(FairshareNode receiver) {
return this.hostQueues.get(receiver).get(0).getSize();
}
/**
* Gets a read-only view on message queue.
*
* @param receiver the receiver
* @return the view on message queue
*/
public List<NetMessage> getViewOnMessageQueue(FairshareNode receiver) {
return Collections.unmodifiableList(this.hostQueues.get(receiver));
}
/**
* Removes the message from queue.
*
* @param receiver the receiver
* @return the net message
*/
public NetMessage removeMessageFromQueue(FairshareNode receiver) {
return this.hostQueues.get(receiver).remove(0);
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
return (obj instanceof FairshareNode) ? ((FairshareNode) obj).getNetID().hashCode() == this.getNetID().hashCode() : super.equals(obj);
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return this.getLocalInetAddress() + " (U:"
+ this.getCurrentBandwidth().getUpBW() + "/D:"
+ this.getCurrentBandwidth().getDownBW() + ")";
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
/* Precomputed to save time. */
return this.hashCode;
}
}
......@@ -48,8 +48,8 @@ public class RealNetworkingNetLayer extends AbstractNetLayer {
private static RealNetworkingNetLayerManager netLayerManager = RealNetworkingNetLayerManager.getInstance();
public RealNetworkingNetLayer(SimHost host, NetID netID) {
super(host, netID, new BandwidthImpl(Double.POSITIVE_INFINITY,
Double.POSITIVE_INFINITY), null, null);
super(host, netID, new BandwidthImpl(Long.MAX_VALUE, Long.MAX_VALUE),
null, null);
/* Go online as default behaviour. */
this.goOnline();
......
......@@ -61,6 +61,7 @@ import de.tud.kom.p2psim.impl.util.toolkits.Dom4jToolkit;
import de.tudarmstadt.maki.simonstrator.api.Binder;
import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.Monitor.Level;
import de.tudarmstadt.maki.simonstrator.api.Rate;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.component.Component;
import de.tudarmstadt.maki.simonstrator.api.component.GlobalComponent;
......@@ -832,16 +833,16 @@ public class DefaultConfigurator implements Configurator {
}
}
}
// Bandwidth (internally used in byte/s)
// Bandwidth (internally used in bit/s)
else if (value.matches("\\d+(Mbps|Kbps|bps)")) {
if (value.matches("\\d+(bps)")) {
factor = 1 / 8;
factor = Rate.bit_s;
number = value.substring(0, value.length() - 3);
} else if (value.matches("\\d+(Kbps)")) {
factor = 1000 / 8;
factor = Rate.kbit_s;
number = value.substring(0, value.length() - 4);
} else if (value.matches("\\d+(Mbps)")) {
factor = 1000000 / 8;
factor = Rate.Mbit_s;
number = value.substring(0, value.length() - 4);
} else {
throw new IllegalStateException("Invalid bandwidth unit.");
......
......@@ -147,7 +147,7 @@ public class DefaultTopologyComponent implements TopologyComponent {
@Override
public void eventOccurred(Object content, int type) {
if (getTopology().getTopologyView(PhyType.WIFI) != null) {
if (getHost().getLinkLayer().hasPhy(PhyType.WIFI)) {
new SiSTopologyProvider(sis, SiSTypes.NEIGHBORS_WIFI,
DefaultTopologyComponent.this, getTopologyID(
NetInterfaceName.WIFI, true),
......
......@@ -42,6 +42,7 @@ import de.tud.kom.p2psim.api.topology.views.TopologyView;
import de.tud.kom.p2psim.impl.topology.PositionVector;
import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.Monitor.Level;
import de.tudarmstadt.maki.simonstrator.api.Rate;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
/**
......@@ -104,6 +105,12 @@ public abstract class AbstractTopologyView<L extends DefaultLink> implements
*/
private boolean movementSupported = false;
/**
* Indicating, that this view is targeted towards the simulations of real
* link layers. See {@link TopologyView}.
*/
private boolean hasRealLinkLayer = false;
/**
* Basic TopologyView, does not support movement
*
......@@ -232,13 +239,13 @@ public abstract class AbstractTopologyView<L extends DefaultLink> implements
*
* @param source
* @param destination
* @return bandwidth in byte/s
* @return bandwidth in bit/s {@link Rate}
*/
protected long determineLinkBandwidth(MacAddress source,
MacAddress destination) {
BandwidthImpl sourceBandwidth = getMac(source).getMaxBandwidth();
BandwidthImpl destinationBandwidth = getMac(destination).getMaxBandwidth();
return (long) Math.min(sourceBandwidth.getUpBW(),
return Math.min(sourceBandwidth.getUpBW(),
destinationBandwidth.getDownBW());
}
......@@ -484,4 +491,19 @@ public abstract class AbstractTopologyView<L extends DefaultLink> implements
return getCachedPosition(addressA)
.distanceTo(getCachedPosition(addressB));
}
@Override
public boolean hasRealLinkLayer() {
return hasRealLinkLayer;
}
/**
* Mark that this {@link TopologyView} has a real link layer (latencies and
* drop rates are Layer 2 measurements!)
*
* @param hasRealLinkLayer
*/
public void setHasRealLinkLayer(boolean hasRealLinkLayer) {
this.hasRealLinkLayer = hasRealLinkLayer;
}
}
......@@ -51,6 +51,7 @@ public class CloudTopologyView extends AbstractTopologyView<DefaultLink> {
public CloudTopologyView(PhyType phy) {
super(phy);
setHasRealLinkLayer(false);
}
@XMLConfigurableConstructor({ "phy" })
......@@ -87,7 +88,7 @@ public class CloudTopologyView extends AbstractTopologyView<DefaultLink> {
protected long determineLinkBandwidth(MacAddress source,
MacAddress destination) {
BandwidthImpl sourceBandwidth = getMac(source).getMaxBandwidth();
return (long) sourceBandwidth.getUpBW();
return sourceBandwidth.getUpBW();
}
@Override
......
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