📄 network.java
字号:
/* * Copyright (c) 2003-2005 The BISON Project * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2 as * published by the Free Software Foundation. * * This program 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ package peersim.core;import peersim.config.Configuration;import java.util.Comparator;import java.util.Arrays;/*** This class forms the basic framework of all simulations.* This is a static singleton which is based on the assumption that we* will simulate only one overlay network at a time.* This allows us to reduce memory usage in many cases by allowing all the* components to directly reach the fields of this class without having to store* a reference.* <p>* The network is a set of nodes implemented via an array list for the* sake of efficiency.* Each node has an array of protocols. The protocols within a node can* interact directly as defined by their implementation, and can be imagined as* processes running in a common local environment (i.e. the node).* This class is called a "network" because, although it is only a set of nodes,* in most simulations there is at least one {@link Linkable} protocol that* defines connections between nodes. In fact, such a {@link Linkable} protocol* layer can be accessed through a {@link peersim.graph.Graph} view* using {@link OverlayGraph}.*/public class Network {// ========================= fields =================================// ==================================================================/*** This config property defines the node class to be used. If not* set, then {@link GeneralNode} will be used.* @config*/private static final String PAR_NODE = "network.node";/*** This config property defines the initial capacity of the overlay network.* If not set then the value of {@value #PAR_SIZE} will be used.* The main purpose of this parameter is that it allows for optimization.* In the case of scenarios when the network needs to grow, setting this to* the maximal expected size of the network avoids reallocation of memory* during the growth of the network.* @see #getCapacity* @config*/private static final String PAR_MAXSIZE = "network.initialCapacity";/*** This config property defines the initial size of the overlay network.* This property is required.* @config*/private static final String PAR_SIZE = "network.size";/*** The node array. This is not a private array which is not nice but* efficiency has the highest priority here. The main purpose is to allow* the package quick reading of the contents in a maximally flexible way.* Nevertheless, methods of this class should be used instead of the array* when modifying the contents.* Because this array is not private,* it is necessary to know that the actual node set is only the first* {@link #size()} items of the array.*/static Node[] node = null;/*** Actual size of the network.*/private static int len;/*** The prototype node which is used to populate the simulation via cloning.* After all the nodes have been cloned, {@link Control} components can be* applied to perform any further initialization.*/public static Node prototype = null;// ====================== initialization ===========================// =================================================================/*** Reads configuration parameters, constructs the prototype node, and* populates the network by cloning the prototype.*/public static void reset() { if( prototype != null ) { // not first experiment while( len>0 ) remove(); // this is to call onKill on all nodes prototype = null; node = null; } len = Configuration.getInt(PAR_SIZE); int maxlen = Configuration.getInt(PAR_MAXSIZE,len); if( maxlen < len ) throw new IllegalArgumentException( PAR_MAXSIZE+" is less than "+PAR_SIZE); node = new Node[maxlen]; // creating prototype node Node tmp = null; if (!Configuration.contains(PAR_NODE)) { System.err.println( "Network: no node defined, using GeneralNode"); tmp = new GeneralNode(""); } else { tmp = (Node) Configuration.getInstance(PAR_NODE); } prototype = tmp; prototype.setIndex(-1); // cloning the nodes if(len > 0 ) { for(int i=0; i<len; ++i) { node[i] = (Node)prototype.clone(); node[i].setIndex(i); } }}/** Disable instance construction */private Network() {}// =============== public methods ===================================// ==================================================================/** Number of nodes currently in the network */public static int size() { return len; }// ------------------------------------------------------------------/*** Sets the capacity of the internal array storing the nodes.* The nodes will remain the same in the same order.* If the new capacity is less than the* old size of the node list, than the end of the list is cut. The nodes that* get removed via this cutting are removed through {@link #remove()}.*/public static void setCapacity(int newSize) { if( node == null || newSize != node.length ) { for(int i=newSize; i<len; ++i) remove(); Node[] newnodes = new Node[newSize]; final int l = Math.min(node.length,newSize); System.arraycopy(node,0,newnodes,0,l); node = newnodes; if( len > newSize ) len = newSize; }}// ------------------------------------------------------------------/*** Returns the maximal number of nodes that can be stored without reallocating* the underlying array to increase capacity.*/public static int getCapacity() { return node.length; }// ------------------------------------------------------------------/*** The node will be appended to the end of the list. If necessary, the* capacity of the internal array is increased.*/public static void add( Node n ) { if(len==node.length) setCapacity(3*node.length/2+1); node[len] = n; n.setIndex(len); len++;}// ------------------------------------------------------------------/*** Returns node with the given index. Note that the same node will normally* have a different index in different times.* This can be used as a random access iterator.* This method does not perform range checks to increase efficiency.* The maximal valid index is {@link #size()}.*/public static Node get( int index ) { return node[index];}// ------------------------------------------------------------------/*** The node at the end of the list is removed. Returns the removed node.* It also sets the fail state of the node to {@link Fallible#DEAD}.*/public static Node remove() { Node n = node[len-1]; // if len was zero this throws and exception node[len-1]=null; len--; n.setFailState(Fallible.DEAD); return n;}// ------------------------------------------------------------------/*** The node with the given index is removed. Returns the removed node.* It also sets the fail state of the node to {@link Fallible#DEAD}.* <p>Look out: the index of the other nodes will not change (the right* hand side of the list is not shifted to the left) except that of the last* node. Only the* last node is moved to the given position and will get index i.*/public static Node remove(int i) { if( i<0 || i>=len ) throw new IndexOutOfBoundsException(""+i); swap(i,len-1); return remove();}// ------------------------------------------------------------------/*** Swaps the two nodes at the given indexes.*/public static void swap(int i, int j) { Node n = node[i]; node[i] = node[j]; node[j] = n; node[j].setIndex(j); node[i].setIndex(i);}// ------------------------------------------------------------------/*** Shuffles the node array. The index of each node is updated accordingly.*/public static void shuffle() { for(int i=len; i>1; i--) swap(i-1, CommonState.r.nextInt(i));}// ------------------------------------------------------------------/*** Sorts the node array. The index of each node is updated accordingly.* @param c The comparator to be used for sorting the nodes. If null, the* natural order of the nodes is used.*/public static void sort(Comparator<? super Node> c) { Arrays.sort(node,0,len,c); for(int i=0; i<len; i++) node[i].setIndex(i);}// ------------------------------------------------------------------public static void test() { System.err.println("number of nodes = "+len); System.err.println("capacity (max number of nodes) = "+node.length); for(int i=0; i<len; ++i) { System.err.println("node["+i+"]"); System.err.println(node[i].toString()); } if(prototype==null) return; for(int i=0; i<prototype.protocolSize(); ++i) { if( prototype.getProtocol(i) instanceof Linkable ) peersim.graph.GraphIO.writeUCINET_DL( new OverlayGraph(i),System.err); }}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -