📄 networkimpl.java
字号:
app = GenericFactory.buildApplication();
node.registerApplication(app,app.getId());
}
}
}
/**
* Returns an array of indexes in range (0..number of nodes) to use
* to identify which nodes to select.
* @param max Number of indexes generate.
* @return An array of indexes with values at range (0..number of nodes) with
* a size of <b>max</b> elements.
*/
protected int[] makeRandomIndexes (int max) {
HashSet indexes = new HashSet(max);
int maxValue = nodes.size();
while (indexes.size() < max) {
indexes.add(new Integer(randomGenerator.nextInt(maxValue)));
}
Integer[] integerIndexes = (Integer[])indexes.toArray();
int[] intIndexes = new int[max];
for (int i=0; i<max; i++) {
intIndexes[i] = integerIndexes[i].intValue();
}
return intIndexes;
}
/**
* Gets the actual topology of the underlying network.
* @see planet.commonapi.Network#getTopology()
* @return A String defining the actual topology of the network.
* @see planet.generic.commonapi.factory.Topology
*/
public String getTopology() {
return topology;
}
/* ***************** DE/SERIALIZE NETWORKIMPL ****************/
/**
* Serialize this instance through the <b>stream</b>. It is
* responsible to generate a correct serialized state.
* @param stream ObjectOutputStream to save the actual state.
* @throws IOException if occurs any problem during serialization.
*/
private void writeObject(java.io.ObjectOutputStream stream)
throws IOException {
//serialized necessary attributes
stream.writeObject(this.nodeFactory);
stream.writeObject(this.nodes);
stream.writeObject(this.toRemove);
stream.writeObject(this.randomGenerator);
stream.writeObject(new Integer(totalSteps));
}
/**
* Reads a serialized state of
* @param stream
* @throws IOException
* @throws ClassNotFoundException
*/
private void readObject(java.io.ObjectInputStream stream)
throws IOException, ClassNotFoundException {
//load serialized attributes
this.nodeFactory = (NodeFactory) stream.readObject();
this.nodes = (TreeMap) stream.readObject();
this.toRemove = (Stack) stream.readObject();
this.randomGenerator = (Random) stream.readObject();
this.totalSteps = ((Integer)stream.readObject()).intValue();
//generate rest of attributes
this.topology = Properties.factoriesNetworkTopology;
this.size = nodes.size();
this.stabLevel = 0;
}
/**
* This method is invoked when cannot read the version of serialized objects
* from the instance of network. In this case, an InvalidObjectException is thrown.
*/
private void readObjectNoData()
throws ObjectStreamException {
throw new InvalidObjectException("Cannot deserialize the network state.");
}
/* *************************** PRINTING BLOCK *******************************/
/**
* Returns the actual number of nodes to the network.
* @see planet.commonapi.Network#size()
* @return The actual number of nodes to the network.
*/
public int size() {
return size;
}
/**
* Shows for each Node its printNode().
*/
public void printNodes() {
Node aNode = null;
Collection c = nodes.values();
Iterator it3 = c.iterator();
while (it3.hasNext()){
aNode = (Node)it3.next();
aNode.printNode();
}
}
/**
* Shows only the owner Id, the successor and predecessor
* for each Node.
*/
public void prettyPrintNodes() {
Node aNode = null;
Collection c = nodes.values();
Iterator it3 = c.iterator();
while (it3.hasNext()){
aNode = (NodeImpl)it3.next();
aNode.prettyPrintNode();
}
}
/* ******************************** SIMULATION BLOCK **************************/
/**
* Simulate a total number <b>steps</b> steps.
* @see planet.commonapi.Network#run(int)
* @param steps Number of steps to simulate.
* @return Number of actual stabilization steps after run <b>steps</b> steps.
*/
public int run(int steps) {
for (int i=0; i< steps; i++) {
simulate();
}
return totalSteps;
}
/**
* Simulate one step.
* @see planet.commonapi.Network#simulate()
* @return true if the simulation process must to continue for
* to finish the stabilization.
*/
public boolean simulate() {
//process all nodes
boolean toContinue = process();
//send all messages
sendMessages();
//remove all pending nodes to be deleted
removeNodes();
totalSteps++;
//to update actual step in Logger utility
Logger.setStep(totalSteps);
return (toContinue //overlay condition
|| Results.getTraffic() > 0); //exist application messages??
}
/**
* Process all nodes one step at this network.
* @return true if continue the simulation. false in other case.
*/
protected boolean process() {
Iterator it = iterator();
Node aNode = null;
//informs that any node requires continue the stabilization process.
boolean toContinue = false;
//Each node process incoming messages and handles additional
//stabilization operations
while (it.hasNext()){
aNode = (Node)it.next();
// always process the node
toContinue = toContinue | aNode.process(this.totalSteps);
if (!aNode.isAlive()) { //the node has failed or leaved??
toRemove.add(aNode.getLocalHandle());
}
}
return toContinue;
}
/**
* Sends all message pending to be delivered by all nodes.
*/
protected boolean sendMessages() {
Iterator it = iterator();
Node aNode = null;
Queue messages = null;
boolean toContinue = false;
// The simulator moves outgoing messages to target's incoming node queues
while (it.hasNext()){
aNode = (Node)it.next();
messages = aNode.outMessages();
toContinue = toContinue | (messages==null || messages.size() > 0);
send(messages);
}
return toContinue;
}
/**
* Takes all messages of queue and send to all destination nodes. If any
* destination of any message is not found, it is returned with mode sets
* to Globals.ERROR.
*
* @param messages Queue with messages to send
* @see planet.util.Queue
* @see planet.simulate.Globals Globals
*/
protected void send (Queue messages) {
//There are messages to process??
if (messages==null) return;
RouteMessage aMessage;
NodeHandle from;
NodeHandle target;
Node aNode;
int processed = 0;
while (!messages.isEmpty() && processed < Properties.simulatorProcessedMessages){
aMessage = (RouteMessage) messages.remove();
target = aMessage.getNextHopHandle();
if (target!=null && nodes.containsKey(target)) {
aNode = (Node)nodes.get(target);
try {
aNode.receive(aMessage);
} catch (QueueFull ex){
Logger.log("Incoming queue of Node "+target+" is full",Logger.EVENT_LOG);
GenericFactory.freeMessage(aMessage);
}
} else {
Logger.log("Target of message ["+aMessage+"] is not found.",Logger.MSG_LOG);
from = aMessage.getSource();
if (nodes.containsKey(from)){
aNode = (Node)nodes.get(from);
aMessage.setMode(Globals.ERROR);
try {
NodeHandle source = aMessage.getSource();
aMessage.setSource(aMessage.getDestination());
aMessage.setDestination(source);
aMessage.setNextHopHandle(source);
aNode.receive(aMessage);
} catch (QueueFull ex) {
Logger.log("Incoming queue of Node "+from+" is full",Logger.EVENT_LOG);
GenericFactory.freeMessage(aMessage);
}
}
}
processed ++;
}
}
/**
* Removes ready nodes to be deleted.
*/
private void removeNodes() {
NodeHandle node = null;
while (!toRemove.isEmpty()){
node = (NodeHandle)toRemove.pop();
nodes.remove(node);
size--;
}
}
/**
* Returns a randomly selected node of actual network.
* @param r Generator of random numbers.
* @return A node radomly selected.
* @see planet.commonapi.Network#getRandomNode(java.util.Random)
*/
public Node getRandomNode(Random r) {
Object[] values = nodes.values().toArray();
int x = r.nextInt(values.length);
return (Node)values[x];
}
/**
* Inform if exist on the network one node with NodeHandle <b>node</b>.
* @param node NodeHandle of the node to be search.
* @return true if and only if exist one node with the same <b>node</b> NodeHandle.
* @see planet.commonapi.Network#existNode(planet.commonapi.NodeHandle)
*/
public boolean existNode(NodeHandle node) {
return nodes.containsKey(node);
}
/**
* Stabilize the network.
* @see planet.commonapi.Network#stabilize()
*/
public int stabilize() {
this.stabLevel = 0;
while (simulate());
return totalSteps;
}
/**
* Gets a reference of some application on any node of the network.
* @param appId Application identification for searching it.
* @return A reference of an existing application on any node or null
* if there is not an Application with the <b>appId</b>.
* @see planet.commonapi.Network#getRandomApplication(java.lang.String)
*/
public Application getRandomApplication(String appId) {
Node randomNode = this.getRandomNode(randomGenerator);
Application[] apps = randomNode.getRegisteredApplications();
boolean found = false;
int i=0;
for (; i<apps.length && !found;i++) {
found = apps[i].getId().equals(appId);
}
//update to correct position
i--;
if (!found)
return null;
return apps[i];
}
/**
* Builds an Iterator to iterate over all nodes of the network.
* @return An Iterator for all nodes on the network.
*/
public Iterator iterator() {
return new NetworkIterator(nodes);
}
/**
* Gets the actual number of simulated steps.
* @see planet.commonapi.Network#getSimulatedSteps()
* @return actual number of simulated steps
*/
public int getSimulatedSteps() {
return totalSteps;
}
/**
* This class implements the java.util.Iterator interface and is backed
* up by TreeMap that contains all existing nodes on the network.
* <br><br>
* It use the iterator of the TreeMap key set to iterate over all instances
* of the nodes, and returns the corresponding Node. It also implements
* the remove() method, that uses the same method of the key set iterator.
* This last method ensures to remove the required entry on to the TreeMap.
*
* @author Jordi Pujol
*/
public class NetworkIterator implements java.util.Iterator {
/**
* HashMap that contains all Nodes to iterate.
*/
private TreeMap nodes = null;
/**
* Iterator of keys existing over the HashMap.
*/
private Iterator keys = null;
/**
* Initialize the key set iterator over the HashMap.
* @param nodes
*/
public NetworkIterator (TreeMap nodes) {
this.nodes = nodes;
this.keys = this.nodes.keySet().iterator();
}
/**
* Evaluate if there are more nodes.
* @see java.util.Iterator#hasNext()
*/
public boolean hasNext() {
return keys.hasNext();
}
/**
* Returns the next Node.
* @see java.util.Iterator#next()
*/
public Object next() {
return nodes.get(keys.next());
}
/**
* Remove the actual element of the HashMap.
* @see java.util.Iterator#remove()
*/
public void remove() {
keys.remove();
}
}
/**
* Always returns 1 (one).
* @see planet.commonapi.Network#getProximity(planet.commonapi.NodeHandle, planet.commonapi.NodeHandle)
* @param nodeA First node to evaluate.
* @param nodeB Second node to evaluate.
* @return The distance between theese two nodes (in this implementation, always one).
*/
public int getProximity(NodeHandle nodeA, NodeHandle nodeB) {
return 1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -