2 * Copyright (c) 2003-2005 The BISON Project
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 2 as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 package peersim.dynamics;
23 import org.simgrid.msg.Host;
24 import org.simgrid.msg.MsgException;
26 import peersim.Simulator;
27 import peersim.config.Configuration;
28 import peersim.core.*;
29 import psgsim.NodeHost;
30 import psgsim.PSGDynamicNetwork;
33 * This {@link Control} can change the size of networks by adding and removing
34 * nodes. Can be used to model churn. This class supports only permanent removal
35 * of nodes and the addition of brand new nodes. That is, temporary downtime is
36 * not supported by this class.
38 public class DynamicNetwork implements Control {
40 // --------------------------------------------------------------------------
42 // --------------------------------------------------------------------------
45 * Config parameter which gives the prefix of node initializers. An
46 * arbitrary number of node initializers can be specified (Along with their
47 * parameters). These will be applied on the newly created nodes. The
48 * initializers are ordered according to alphabetical order if their ID.
52 * control.0 DynamicNetwork
53 * control.0.init.0 RandNI
54 * control.0.init.0.k 5
55 * control.0.init.0.protocol somelinkable
61 private static final String PAR_INIT = "init";
64 * If defined, nodes are substituted (an existing node is removed, a new one
65 * is added. That is, first the number of nodes to add (or remove if
66 * {@value #PAR_ADD} is negative) is calculated, and then exactly the same
67 * number of nodes are removed (or added) immediately so that the network
68 * size remains constant. Not set by default.
72 private static final String PAR_SUBST = "substitute";
75 * Specifies the number of nodes to add or remove. It can be negative in
76 * which case nodes are removed. If its absolute value is less than one,
77 * then it is interpreted as a proportion of current network size, that is,
78 * its value is substituted with <tt>add*networksize</tt>. Its value is
79 * rounded to an integer.
83 private static final String PAR_ADD = "add";
86 * Nodes are added until the size specified by this parameter is reached.
87 * The network will never exceed this size as a result of this class. If not
88 * set, there will be no limit on the size of the network.
92 private static final String PAR_MAX = "maxsize";
95 * Nodes are removed until the size specified by this parameter is reached.
96 * The network will never go below this size as a result of this class.
101 private static final String PAR_MIN = "minsize";
103 // --------------------------------------------------------------------------
105 // --------------------------------------------------------------------------
107 /** value of {@value #PAR_ADD} */
108 protected final double add;
110 /** value of {@value #PAR_SUBST} */
111 protected final boolean substitute;
113 /** value of {@value #PAR_MIN} */
114 protected final int minsize;
116 /** value of {@value #PAR_MAX} */
117 protected final int maxsize;
119 /** node initializers to apply on the newly added nodes */
120 protected final NodeInitializer[] inits;
122 // --------------------------------------------------------------------------
124 // --------------------------------------------------------------------------
127 * Adds n nodes to the network. Extending classes can implement any
128 * algorithm to do that. The default algorithm adds the given number of
129 * nodes after calling all the configured initializers on them.
132 * the number of nodes to add, must be non-negative.
134 protected void add(int n) {
135 for (int i = 0; i < n; ++i) {
136 Node newnode = (Node) Network.prototype.clone();
137 for (int j = 0; j < inits.length; ++j) {
138 inits[j].initialize(newnode);
140 Network.add(newnode);
145 // ------------------------------------------------------------------
148 * Removes n nodes from the network. Extending classes can implement any
149 * algorithm to do that. The default algorithm removes <em>random</em> nodes
150 * <em>permanently</em> simply by calling {@link Network#remove(int)}.
153 * the number of nodes to remove
155 protected void remove(int n) {
156 for (int i = 0; i < n; ++i) {
157 int nr = CommonState.r.nextInt(Network.size());
163 // --------------------------------------------------------------------------
165 // --------------------------------------------------------------------------
168 * Standard constructor that reads the configuration parameters. Invoked by
169 * the simulation engine.
172 * the configuration prefix for this class
174 public DynamicNetwork(String prefix) {
175 add = Configuration.getDouble(prefix + "." + PAR_ADD);
176 substitute = Configuration.contains(prefix + "." + PAR_SUBST);
177 Object[] tmp = Configuration.getInstanceArray(prefix + "." + PAR_INIT);
178 inits = new NodeInitializer[tmp.length];
179 for (int i = 0; i < tmp.length; ++i) {
180 // System.out.println("Inits " + tmp[i]);
181 inits[i] = (NodeInitializer) tmp[i];
183 maxsize = Configuration.getInt(prefix + "." + PAR_MAX,
185 minsize = Configuration.getInt(prefix + "." + PAR_MIN, 0);
188 // --------------------------------------------------------------------------
190 // --------------------------------------------------------------------------
193 * Calls {@link #add(int)} or {@link #remove} with the parameters defined by
196 * @return always false
198 public final boolean execute() {
202 if ((maxsize <= Network.size() && add > 0)
203 || (minsize >= Network.size() && add < 0))
209 toadd = (int) Math.round(add < 1 ? add * Network.size() : add);
210 if (!substitute && toadd > maxsize - Network.size())
211 toadd = maxsize - Network.size();
214 } else if (add < 0) {
215 toremove = (int) Math
216 .round(add > -1 ? -add * Network.size() : -add);
217 if (!substitute && toremove > Network.size() - minsize)
218 toremove = Network.size() - minsize;
227 // --------------------------------------------------------------------------