package org.lucci.madhoc.network.net;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import org.lucci.madhoc.network.Application;
import org.lucci.madhoc.network.ComputerUnit;
import org.lucci.madhoc.network.Connection;
import org.lucci.madhoc.network.Station;
import org.lucci.madhoc.network.util.Graph;
import org.lucci.madhoc.simulation.Simulation;
public class NetworkingUnit extends ComputerUnit
{
private static int instanceCount = 0;
private int id = instanceCount++;
private MessageBuffer incomingMessageQueue = new MessageBuffer();
private MessageBuffer outgoingMessageQueue = new MessageBuffer();
private Collection<NetworkInterface> networkAdapters = new Vector<NetworkInterface>();
private Collection<Station> neighborStations;
private Collection<Connection> connections;
public void configure()
throws Throwable
{
Simulation simulation = getStation().getNetwork().getSimulation();
int size = simulation.getConfiguration().getInteger("communicating_device_outgoing_message_queue_size");
getOutgoingMessageQueue().setMaximumSize((int) (size * simulation.getResolution()));
int size2 = simulation.getConfiguration().getInteger("computer_application_incoming_message_queue_size");
getIncomingMessageQueue().setMaximumSize((int) (size2 * simulation.getResolution()));
while (getNetworkInterfaces().isEmpty())
{
Iterator networkTechnologyIterator = getStation().getNetwork().getNetworkTypes().values().iterator();
while (networkTechnologyIterator.hasNext())
{
NetworkingTechnology networkTechnology = (NetworkingTechnology) networkTechnologyIterator.next();
if (getStation().getNetwork().getSimulation().getRandomNumberGenerator().getRandom().nextDouble()
< simulation.getConfiguration().getDouble("network_" + getStation().getType().getName() + "_" + networkTechnology.getName() + "_probability"))
{
NetworkInterface networkAdapter = new NetworkInterface();
networkAdapter.setNetworkingUnit(this);
networkAdapter.setNetworkingTechnology(networkTechnology);
getNetworkInterfaces().add(networkAdapter);
}
}
}
}
public Collection<Station> getNeighborhood()
{
if ( neighborStations == null )
{
neighborStations = new HashSet<Station>();
for (NetworkInterface networkAdapter : getNetworkInterfaces())
{
for (NetworkInterface neighborInterface : networkAdapter.getNeighborhood())
{
neighborStations.add(neighborInterface.getNetworkingUnit().getStation());
}
}
}
return Collections.unmodifiableCollection(neighborStations);
}
public Collection<Application> getApplicationsInTheNeighborhood(Class clazz)
{
Collection<Application> apps = new HashSet<Application>();
Iterator i = getNeighborhood().iterator();
while (i.hasNext())
{
Station s = (Station) i.next();
Application app = (Application) s.getApplicationMap().getValue(clazz);
if (app != null)
{
apps.add(app);
}
}
return apps;
}
public MessageBuffer getOutgoingMessageQueue()
{
return outgoingMessageQueue;
}
public Collection<NetworkInterface> getNetworkInterfaces()
{
return networkAdapters;
}
public NetworkInterface getNetworkInterface(NetworkingTechnology networkType)
{
Iterator networkAdapterIterator = getNetworkInterfaces().iterator();
while (networkAdapterIterator.hasNext())
{
NetworkInterface networkAdapter = (NetworkInterface) networkAdapterIterator.next();
if (networkAdapter.getNetworkingTechnology() == networkType)
{
return networkAdapter;
}
}
return null;
}
public int hashCode()
{
return id;
}
public Collection<Connection> getConnections()
{
if (connections == null)
{
connections = new Vector<Connection>();
Iterator networkAdapterIterator = getNetworkInterfaces().iterator();
while (networkAdapterIterator.hasNext())
{
NetworkInterface networkAdapter = (NetworkInterface) networkAdapterIterator.next();
connections.addAll(networkAdapter.getConnections());
}
connections = Collections.unmodifiableCollection(connections);
}
return connections;
}
public Collection<Connection> getConnectionsTo(Station station)
{
Collection<Connection> set = new Vector<Connection>();
Iterator networkAdapterIterator = getNetworkInterfaces().iterator();
while (networkAdapterIterator.hasNext())
{
NetworkInterface networkAdapter = (NetworkInterface) networkAdapterIterator.next();
Iterator connectionIterator = networkAdapter.getConnections().iterator();
while (connectionIterator.hasNext())
{
Connection c = (Connection) connectionIterator.next();
if (c.getSibbling(networkAdapter).getNetworkingUnit().getStation() == station)
{
set.add(c);
}
}
}
return set;
}
public Connection getBestConnectionTo(Station station)
{
Collection<Connection> set = getConnectionsTo(station);
if (set.isEmpty())
{
return null;
}
else
{
Iterator i = getConnectionsTo(station).iterator();
Connection best = (Connection) set.iterator().next();
while (i.hasNext())
{
Connection c = (Connection) i.next();
if (c.getAvailableBandwith() > best.getAvailableBandwith())
{
best = c;
}
}
return best;
}
}
private Collection<Connection> previousConnections = null;
private Collection<Connection> newConnections;
public Collection<Connection> getNewConnections()
{
if (newConnections == null)
{
if (previousConnections == null)
{
previousConnections = new HashSet<Connection>(getConnections());
newConnections = new HashSet<Connection>();
}
else
{
Collection<Connection> currentConnections = getConnections();
newConnections = new HashSet<Connection>(currentConnections);
newConnections.removeAll(previousConnections);
previousConnections = currentConnections;
}
}
return newConnections;
}
public Collection<Station> getNeighborhoodAtHop(int hop)
{
if (hop < 0)
throw new IllegalArgumentException();
List<Collection<Station>> hops = Graph.getHops(this, hop);
if (hop < hops.size())
{
return (Collection<Station>) hops.get(hop);
}
else
{
return new Vector<Station>();
}
}
public void resetIterationScopedValues()
{
neighborStations = null;
connections = null;
newConnections = null;
}
public MessageBuffer getIncomingMessageQueue()
{
return incomingMessageQueue;
}
}