This was not more visible or better maintained here.
It was just useless code dupplication.
See also https://github.com/mquinson/simgrid/issues/64
+++ /dev/null
-LIB_JARS= lib.jar
-
-all: compile doc
-
-compile:
- mkdir -p classes
- javac -sourcepath src -classpath $(LIB_JARS):../../simgrid.jar -d classes `find -L -name "*.java"`
-doc:
- mkdir -p doc
- javadoc -sourcepath src -classpath $(LIB_JARS):../../simgrid.jar -d doc psgsim
-test:
- ./test.sh
-clean:
- rm -rf classes doc outputs
-help:
- @echo "The following are a valid targets for this Makefile:"
- @echo "................ all (the default if no target is provided)"
- @echo "................ compile"
- @echo "................ doc"
- @echo "................ test"
- @echo "................ clean"
-
+++ /dev/null
-Mon Jan 26 16:00 CEST 2015
-This is version 1.0 of PeerSimGrid
-
-1) An overview
-2) Preliminaries
-3) Compile & Run
-
---------------------------------------------------------------------------------------------
-1) An overview:
-PeerSimGrid (PSG) is an interface developed in Java and allows users to simulate
-and execute their code under PeerSim or Simgrid simulator, using PeerSim implementation policy.
-
-This archive is composed of:
-* the src/ directory containing the simulator source and examples
-* the configs/ directory containing example of configuration files
-* psg.jar, a java archive containing all libraries
-
-
-2) Preliminaries:
- Before using psg simulator, you need to make some changes in your configuration file:
- * Replace the "UniformRandomTransport" transport protocol by "psgsim.PSGTransport".
- * Replace the "simulation.endtime" by "simulation.duration"
- * you can define your platform on the configuration file as:
- platform path/to/your/file.xml
-
-
-3) Compile & Run:
- In short, the way to compile and execute your code is:
- Compile it:
- $> make compile
-
- Test it (optional):
- $> make test
- This test execute two examples, (chord and edaggregation found in the example folder), under the two simulators
- and compare their outputs.
-
- Run it:
- $> ./run.sh path/to/your/configuration_file
- For example:
- $>./run.sh configs/chordPSG.txt
-
- For the documentation
- $> make doc
-
- For the help command
- $> make help
-
-Note: For more informations please contact khaled.baati@gmail.com
\ No newline at end of file
+++ /dev/null
-#Config file for BitTorrent extension
-
-random.seed 1234567890
-simulation.endtime 1800000#6^8
-simulation.logtime 10^3
-OutputName bittorrent
-simulation.experiments 1
-
-network.size 30
-network.node peersim.core.GeneralNode
-
-protocol.urt UniformRandomTransport
-protocol.urt.mindelay 10
-protocol.urt.maxdelay 400
-
-#BE AWARE: the value "max_swarm_size" must be greater than
-#the value "peerset_size", since I have to be sure
-#that the space for the neighbor nodes is enough.
-
-protocol.bittorrent example.bittorrent.BitTorrent
-protocol.bittorrent.file_size 100
-protocol.bittorrent.max_swarm_size 80
-protocol.bittorrent.peerset_size 50
-protocol.bittorrent.duplicated_requests 1
-protocol.bittorrent.transport urt
-protocol.bittorrent.max_growth 20
-
-init.net example.bittorrent.NetworkInitializer
-init.net.protocol bittorrent
-init.net.transport urt
-init.net.newer_distr 80
-init.net.seeder_distr 15
-
-control.observer example.bittorrent.BTObserver
-control.observer.protocol bittorrent
-control.observer.step 10000
-
-control.dynamics example.bittorrent.NetworkDynamics
-control.dynamics.protocol bittorrent
-control.dynamics.newer_distr 60
-control.dynamics.minsize 20
-control.dynamics.tracker_can_die 1
-control.dynamics.step 100000
-control.dynamics.transport urt
-control.dynamics.add 0#5
-control.dynamics.remove 0#5
\ No newline at end of file
+++ /dev/null
-#Config file for BitTorrent extension
-OutputName bittorrent
-platform platforms/psg.xml
-unit ms
-random.seed 1234567890
-simulation.duration 1800000
-simulation.logtime 10^3
-
-simulation.experiments 1
-
-network.size 40
-network.node peersim.core.GeneralNode
-
-protocol.urt psgsim.PSGTransport
-protocol.urt.mindelay 0#10
-protocol.urt.maxdelay 0#400
-
-#BE AWARE: the value "max_swarm_size" must be greater than
-#the value "peerset_size", since I have to be sure
-#that the space for the neighbor nodes is enough.
-
-protocol.bittorrent example.bittorrent.BitTorrent
-protocol.bittorrent.file_size 100
-protocol.bittorrent.max_swarm_size 80
-protocol.bittorrent.peerset_size 50
-protocol.bittorrent.duplicated_requests 1
-protocol.bittorrent.transport urt
-protocol.bittorrent.max_growth 20
-
-init.net example.bittorrent.NetworkInitializer
-init.net.protocol bittorrent
-init.net.transport urt
-init.net.newer_distr 80
-init.net.seeder_distr 15
-
-control.observer example.bittorrent.BTObserver
-control.observer.protocol bittorrent
-control.observer.step 10000
-
-control.dynamics example.bittorrent.NetworkDynamics
-control.dynamics.protocol bittorrent
-control.dynamics.newer_distr 60
-control.dynamics.minsize 20
-control.dynamics.tracker_can_die 1
-control.dynamics.step 100000
-control.dynamics.transport urt
-control.dynamics.add 0#5
-control.dynamics.remove 0#5
\ No newline at end of file
+++ /dev/null
-# PEERSIM CHORD\r
-\r
-random.seed 1234567890\r
-simulation.endtime 10^4\r
-simulation.logtime 10^6\r
-OutputName chord\r
-simulation.experiments 1\r
-\r
-network.size 40\r
-protocol.tr UniformRandomTransport\r
-{\r
- mindelay 0\r
- maxdelay 0\r
-}\r
-\r
-protocol.chord example.chord.ChordProtocol\r
-{\r
- transport tr\r
-}\r
-\r
-control.traffic example.chord.TrafficGenerator\r
-{\r
- protocol chord\r
- step 100\r
-}\r
-\r
-init.create example.chord.CreateNw \r
-{\r
- protocol chord\r
- idLength 128\r
- succListSize 12\r
-}\r
-\r
-control.observer example.chord.MessageCounterObserver\r
-{\r
- protocol chord\r
- step 90000\r
-}\r
-\r
-#control.dnet DynamicNetwork\r
-#{\r
-# #add 2\r
-# add -2\r
-# minsize 18#3000\r
-# maxsize 60#7000\r
-# step 100000\r
-# init.0 example.chord.ChordInitializer\r
-# { \r
-# protocol chord\r
-# }\r
-#}
\ No newline at end of file
+++ /dev/null
-# PEERSIM CHORD\r
-\r
-random.seed 1234567890\r
-simulation.duration 10^4\r
-simulation.logtime 10^6\r
-unit sec\r
-OutputName chord\r
-platform platforms/psg.xml\r
-simulation.experiments 1\r
-\r
-network.size 40\r
-protocol.tr psgsim.PSGTransport\r
-{\r
- mindelay 0\r
- maxdelay 0\r
-}\r
-\r
-protocol.chord example.chord.ChordProtocol\r
-{\r
- transport tr\r
-}\r
-\r
-control.traffic example.chord.TrafficGenerator\r
-{\r
- protocol chord\r
- step 100\r
-}\r
-\r
-init.create example.chord.CreateNw \r
-{\r
- protocol chord\r
- idLength 128\r
- succListSize 12\r
-}\r
-\r
-control.observer example.chord.MessageCounterObserver\r
-{\r
- protocol chord\r
- step 90000\r
-}\r
-\r
-\r
-#control.dnet DynamicNetwork\r
-#{\r
-# #add 2\r
-# add -2\r
-# minsize 18#3000\r
-# maxsize 60#7000\r
-# step 100000\r
-# init.0 example.chord.ChordInitializer\r
-# { \r
-# protocol chord\r
-# }\r
-#}\r
+++ /dev/null
-# network size
-SIZE 50
-OutputName edaggregation
-
-# parameters of periodic execution
-CYCLES 100
-CYCLE SIZE*100
-
-# parameters of message transfer
-# delay values here are relative to cycle length, in percentage,
-# eg 50 means half the cycle length, 200 twice the cycle length, etc.
-MINDELAY 0
-MAXDELAY 0
-# drop is a probability, 0<=DROP<=1
-DROP 0
-
-random.seed 1234567890
-network.size SIZE
-simulation.endtime CYCLE*CYCLES
-simulation.logtime CYCLE
-
-################### protocols ===========================
-
-protocol.link peersim.core.IdleProtocol
-
-protocol.avg example.edaggregation.AverageED
-protocol.avg.linkable link
-protocol.avg.step CYCLE
-protocol.avg.transport tr
-
-protocol.tr UnreliableTransport
-protocol.tr.transport urt
-protocol.tr.drop DROP
-
-protocol.urt UniformRandomTransport
-protocol.urt.mindelay (CYCLE*MINDELAY)/100
-protocol.urt.maxdelay (CYCLE*MAXDELAY)/100
-################### initialization ======================
-
-init.rndlink WireKOut
-init.rndlink.k 20
-init.rndlink.protocol link
-
-init.vals LinearDistribution
-init.vals.protocol avg
-init.vals.max SIZE
-init.vals.min 1
-
-init.sch CDScheduler
-init.sch.protocol avg
-init.sch.randstart
-
-################ control ==============================
-
-control.0 SingleValueObserver
-control.0.protocol avg
-control.0.step CYCLE
+++ /dev/null
-# network size
-SIZE 50
-OutputName edaggregation
-platform platforms/psg.xml
-unit sec
-# parameters of periodic execution
-CYCLES 100
-CYCLE SIZE*100
-# parameters of message transfer
-# delay values here are relative to cycle length, in percentage,
-# eg 50 means half the cycle length, 200 twice the cycle length, etc.
-MINDELAY 0
-MAXDELAY 0
-# drop is a probability, 0<=DROP<=1
-DROP 0
-
-random.seed 1234567890
-network.size SIZE
-simulation.duration CYCLE*CYCLES
-simulation.logtime CYCLE
-
-################### protocols ===========================
-
-protocol.link peersim.core.IdleProtocol
-
-protocol.avg example.edaggregation.AverageED
-protocol.avg.linkable link
-protocol.avg.step CYCLE
-protocol.avg.transport tr
-
-protocol.tr UnreliableTransport
-protocol.tr.transport urt
-protocol.tr.drop DROP
-
-protocol.urt psgsim.PSGTransport
-protocol.urt.mindelay (CYCLE*MINDELAY)/100
-protocol.urt.maxdelay (CYCLE*MAXDELAY)/100
-################### initialization ======================
-
-init.rndlink WireKOut
-init.rndlink.k 20
-init.rndlink.protocol link
-
-init.vals LinearDistribution
-init.vals.protocol avg
-init.vals.max SIZE
-init.vals.min 1
-
-init.sch CDScheduler
-init.sch.protocol avg
-init.sch.randstart
-
-################ control ==============================
-
-control.0 SingleValueObserver
-control.0.protocol avg
-control.0.step CYCLE
+++ /dev/null
-# ::::::::::::::::::::::::::::::::::::::::::::::::::::::\r
-# :: Symphony Default Configuration\r
-# ::::::::::::::::::::::::::::::::::::::::::::::::::::::\r
-\r
-# network size\r
-SIZE 50\r
-\r
-# parameters of periodic execution\r
-CYCLES 100\r
-CYCLE SIZE/2\r
-OutputName symphony\r
-\r
-# parameters of message transfer\r
-# delay values here are relative to cycle length, in percentage,\r
-# eg 50 means half the cycle length, 200 twice the cycle length, etc.\r
-MINDELAY 0\r
-MAXDELAY 0\r
-\r
-random.seed 1234567890\r
-network.size SIZE\r
-simulation.experiments 1\r
-simulation.endtime 2000#CYCLE*CYCLES\r
-simulation.logtime CYCLE\r
-\r
-################### transports ===========================\r
-\r
-protocol.tr UniformRandomTransport \r
-{\r
- mindelay (CYCLE*MINDELAY)/100\r
- maxdelay (CYCLE*MAXDELAY)/100\r
-}\r
-\r
-################### protocols ===========================\r
-\r
-order.protocol link networkestimator symphony symphonynetworkmanager\r
-\r
-protocol.link peersim.core.IdleProtocol\r
-\r
-protocol.symphony example.symphony.SymphonyProtocol\r
-{\r
- linkable link\r
- transport tr\r
- shortlink 4\r
- # if commented means: longlink log(n)\r
- #longlink 4\r
- routing unidirectional\r
- lookahead off\r
-}\r
-\r
-#protocol.networkestimator example.symphony.SimpleNetworkSizeEstimatorProtocol\r
-\r
-protocol.networkestimator example.symphony.SymphonyEstimationProtocol\r
-{\r
- symphony symphony\r
- # if commented means: s log(n)\r
- #s 3\r
-}\r
-\r
-protocol.symphonynetworkmanager example.symphony.SymphonyNetworkManager\r
-{\r
- symphony symphony\r
- transport tr\r
- networkestimator networkestimator\r
- attempts 3\r
- nTimeout 5\r
- relinking on\r
- relinkingLowerBound 0.5\r
- relinkingUpperBound 2.0\r
- step 4*CYCLE #useless\r
-}\r
-\r
-################### initialization ======================\r
-\r
-order.init netbuild checknet\r
-\r
-init.netbuild example.symphony.SymphonyNetworkBuilder\r
-{\r
- symphony symphony\r
- createLongLinks true\r
- attempts 5\r
-}\r
-\r
-init.checknet example.symphony.SymphonyNetworkChecker\r
-{\r
- symphony symphony\r
- networkestimator networkestimator\r
-}\r
-\r
-################ control ==============================\r
-\r
-order.control sch checknet randomroutetest ringroutetest leavetest dnet estimationtest statistics\r
-\r
-control.randomroutetest example.symphony.RandomRouteTest\r
-{\r
- symphony symphony\r
- step CYCLE\r
-}\r
-\r
-control.ringroutetest example.symphony.RingRouteTest\r
-{\r
- symphony symphony\r
- startnode 0\r
- step CYCLE\r
-}\r
-\r
-control.sch CDScheduler\r
-{\r
- protocol symphonynetworkmanager\r
- step CYCLE*2\r
- randstart\r
-}\r
-\r
-control.checknet example.symphony.SymphonyNetworkChecker\r
-{\r
- symphony symphony\r
- networkestimator networkestimator\r
- step CYCLE\r
-}\r
-\r
-control.dnet peersim.dynamics.DynamicNetwork\r
-{\r
- add 0\r
- maxsize 50\r
- minsize SIZE/2\r
- step CYCLE*2\r
- init.0 example.symphony.SymphonyNodeInizializer\r
- {\r
- symphonynetworkmanager symphonynetworkmanager\r
- symphony symphony\r
- bootstrapnode 0\r
- }\r
-}\r
-\r
-control.leavetest example.symphony.LeaveTest\r
-{\r
- symphonynetworkmanager symphonynetworkmanager\r
- n 1\r
- minsizeOnline SIZE-1\r
- waitTargetSizeToStart 2*SIZE\r
- step CYCLE*2\r
-}\r
-\r
-control.statistics example.symphony.SymphonyStatistics\r
-{\r
- symphony symphony\r
- step (CYCLE*CYCLES)-1\r
-}\r
-\r
-control.estimationtest example.symphony.test.NetworkEstimationTest\r
-{\r
- symphony symphony\r
- symphonynetworkmanager symphonynetworkmanager\r
- step CYCLE*4\r
-}
\ No newline at end of file
+++ /dev/null
-# ::::::::::::::::::::::::::::::::::::::::::::::::::::::\r
-# :: Symphony Default Configuration\r
-# ::::::::::::::::::::::::::::::::::::::::::::::::::::::\r
-\r
-# network size\r
-SIZE 50\r
-unit sec\r
-# parameters of periodic execution\r
-CYCLES 100\r
-CYCLE SIZE/2\r
-OutputName symphony\r
-platform platforms/psg.xml\r
-\r
-# parameters of message transfer\r
-# delay values here are relative to cycle length, in percentage,\r
-# eg 50 means half the cycle length, 200 twice the cycle length, etc.\r
-MINDELAY 0\r
-MAXDELAY 0\r
-\r
-random.seed 1234567890\r
-network.size SIZE\r
-simulation.experiments 1\r
-simulation.duration 2000#CYCLE*CYCLES\r
-simulation.logtime CYCLE\r
-\r
-################### transports ===========================\r
-\r
-protocol.tr psgsim.PSGTransport \r
-{\r
- mindelay (CYCLE*MINDELAY)/100\r
- maxdelay (CYCLE*MAXDELAY)/100\r
-}\r
-\r
-################### protocols ===========================\r
-\r
-order.protocol link networkestimator symphony symphonynetworkmanager\r
-\r
-protocol.link peersim.core.IdleProtocol\r
-\r
-protocol.symphony example.symphony.SymphonyProtocol\r
-{\r
- linkable link\r
- transport tr\r
- shortlink 4\r
- # if commented means: longlink log(n)\r
- #longlink 4\r
- routing unidirectional\r
- lookahead off\r
-}\r
-\r
-#protocol.networkestimator example.symphony.SimpleNetworkSizeEstimatorProtocol\r
-\r
-protocol.networkestimator example.symphony.SymphonyEstimationProtocol\r
-{\r
- symphony symphony\r
- # if commented means: s log(n)\r
- #s 3\r
-}\r
-\r
-protocol.symphonynetworkmanager example.symphony.SymphonyNetworkManager\r
-{\r
- symphony symphony\r
- transport tr\r
- networkestimator networkestimator\r
- attempts 3\r
- nTimeout 5\r
- relinking on\r
- relinkingLowerBound 0.5\r
- relinkingUpperBound 2.0\r
- step 4*CYCLE #useless\r
-}\r
-\r
-################### initialization ======================\r
-\r
-order.init netbuild checknet\r
-\r
-init.netbuild example.symphony.SymphonyNetworkBuilder\r
-{\r
- symphony symphony\r
- createLongLinks true\r
- attempts 5\r
-}\r
-\r
-init.checknet example.symphony.SymphonyNetworkChecker\r
-{\r
- symphony symphony\r
- networkestimator networkestimator\r
-}\r
-\r
-################ control ==============================\r
-\r
-order.control sch checknet randomroutetest ringroutetest leavetest dnet estimationtest statistics\r
-\r
-control.randomroutetest example.symphony.RandomRouteTest\r
-{\r
- symphony symphony\r
- step CYCLE\r
-}\r
-\r
-control.ringroutetest example.symphony.RingRouteTest\r
-{\r
- symphony symphony\r
- startnode 0\r
- step CYCLE\r
-}\r
-\r
-control.sch CDScheduler\r
-{\r
- protocol symphonynetworkmanager\r
- step CYCLE*2\r
- randstart\r
-}\r
-\r
-control.checknet example.symphony.SymphonyNetworkChecker\r
-{\r
- symphony symphony\r
- networkestimator networkestimator\r
- step CYCLE\r
-}\r
-\r
-control.dnet peersim.dynamics.DynamicNetwork\r
-{\r
- add 0\r
- maxsize 50\r
- minsize SIZE/2\r
- step CYCLE*2\r
- init.0 example.symphony.SymphonyNodeInizializer\r
- {\r
- symphonynetworkmanager symphonynetworkmanager\r
- symphony symphony\r
- bootstrapnode 0\r
- }\r
-}\r
-\r
-control.leavetest example.symphony.LeaveTest\r
-{\r
- symphonynetworkmanager symphonynetworkmanager\r
- n 1\r
- minsizeOnline SIZE-1\r
- waitTargetSizeToStart 2*SIZE\r
- step CYCLE*2\r
-}\r
-\r
-control.statistics example.symphony.SymphonyStatistics\r
-{\r
- symphony symphony\r
- step (CYCLE*CYCLES)-1\r
-}\r
-\r
-control.estimationtest example.symphony.test.NetworkEstimationTest\r
-{\r
- symphony symphony\r
- symphonynetworkmanager symphonynetworkmanager\r
- step CYCLE*4\r
-}\r
+++ /dev/null
-<?xml version='1.0'?>
-<!DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid/simgrid.dtd">
-<platform version="4">
-<!-- _________
- | |
- | router |
- ____________|__________|_____________ backbone
- | | | | | |
- l0| l1| l2| l97| l96 | | l99
- | | | ........ | | |
- | |
- c-0.me c-99.me -->
-
-<config> <prop id="network/latency_factor" value="1.0"/></config>
-
-<AS id="AS0" routing="Full">
- <cluster id="my_cluster_1" prefix="" suffix="" radical="0-50000" speed="1Gf" bw="200Mbps" lat="0ms"
- bb_bw="200Mbps" bb_lat="0ms"/>
-</AS>
-</platform>
+++ /dev/null
-#!/bin/bash
-
-if [ $(uname -m) = "i686" ]; then
- eval ulimit -s 64
-else
- eval ulimit -s 128
-fi
-echo '------------- Start execution..';
-java -Xmx1024m -cp lib.jar:classes:../../simgrid.jar peersim.Simulator $1
-echo '------------- done -------------';
-exit 0
-
-
-
-
+++ /dev/null
-/*
- * Copyright (c) 2007-2008 Fabrizio Frioli, Michele Pedrolli
- *
- * 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.
- *
- * --
- *
- * Please send your questions/suggestions to:
- * {fabrizio.frioli, michele.pedrolli} at studenti dot unitn dot it
- *
- */
-
-package example.bittorrent;
-
-import peersim.config.*;
-import peersim.core.*;
-import peersim.util.*;
-
-/**
- * This {@link Control} provides a way to keep track of some
- * parameters of the BitTorrent network.
- */
- public class BTObserver implements Control {
-
- /**
- * The protocol to operate on.
- * @config
- */
- private static final String PAR_PROT="protocol";
-
- /**
- * Protocol identifier, obtained from config property
- */
- private final int pid;
-
- /**
- * The basic constructor that reads the configuration file.
- * @param prefix the configuration prefix for this class
- */
- public BTObserver(String prefix) {
- pid = Configuration.getPid(prefix + "." + PAR_PROT);
- }
-
- /**
- * Prints information about the BitTorrent network
- * and the number of leechers and seeders.
- * Please refer to the code comments for more details.
- * @return always false
- */
- public boolean execute() {
- IncrementalFreq nodeStatusStats = new IncrementalFreq();
- IncrementalStats neighborStats = new IncrementalStats();
-
- int numberOfNodes = Network.size();
- int numberOfCompletedPieces = 0;
-
- // cycles from 1, since the node 0 is the tracker
- for (int i=1; i<numberOfNodes; ++i) {
-
- // stats on number of leechers and seeders in the network
- // and consequently also on number of completed files in the network
- nodeStatusStats.add(((BitTorrent)(Network.get(i).getProtocol(pid))).getPeerStatus());
-
- // stats on number of neighbors per peer
- neighborStats.add(((BitTorrent)(Network.get(i).getProtocol(pid))).getNNodes());
- }
-
- // number of the pieces of the file, equal for every node, here 1 is chosen,
- // since 1 is the first "normal" node (0 is the tracker)
- int numberOfPieces = ((BitTorrent)(Network.get(1).getProtocol(pid))).nPieces;
-
- for (int i=1; i<numberOfNodes; ++i) {
- numberOfCompletedPieces = 0;
-
- // discovers the status of the current peer (leecher or seeder)
- int ps = ((BitTorrent)(Network.get(i).getProtocol(pid))).getPeerStatus();
- String peerStatus;
- if (ps==0) {
- peerStatus = "L"; //leecher
- }
- else {
- peerStatus = "S"; //seeder
- }
-
-
- if (Network.get(i)!=null) {
-
- // counts the number of completed pieces for the i-th node
- for (int j=0; j<numberOfPieces; j++) {
- if ( ((BitTorrent)(Network.get(i).getProtocol(pid))).getFileStatus()[j] == 16) {
- numberOfCompletedPieces++;
- }
- }
-
- /*
- * Put here the output lines of the Observer. An example is provided with
- * basic information and stats.
- * CommonState.getTime() is used to print out time references
- * (useful for graph plotting).
- */
-
- System.out.println("OBS: node " + ((BitTorrent)(Network.get(i).getProtocol(pid))).getThisNodeID() + "(" + peerStatus + ")" + "\t pieces completed: " + numberOfCompletedPieces + "\t \t down: " + ((BitTorrent)(Network.get(i).getProtocol(pid))).nPiecesDown + "\t up: " + ((BitTorrent)(Network.get(i).getProtocol(pid))).nPiecesUp + " time: " + CommonState.getTime());
- //System.out.println("[OBS] t " + CommonState.getTime() + "\t pc " + numberOfCompletedPieces + "\t n " + ((BitTorrent)(Network.get(i).getProtocol(pid))).getThisNodeID());
- //System.out.println( CommonState.getTime() + "\t" + numberOfCompletedPieces + "\t" + ((BitTorrent)(Network.get(i).getProtocol(pid))).getThisNodeID());
-
- }
- else {
- //System.out.println("[OBS] t " + CommonState.getTime() + "\t pc " + "0" + "\t n " + "0");
- }
-
- }
-
- // prints the frequency of 0 (leechers) and 1 (seeders)
- nodeStatusStats.printAll(System.out);
-
- // prints the average number of neighbors per peer
- System.out.println("Avg number of neighbors per peer: " + neighborStats.getAverage());
-
- return false;
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2007-2008 Fabrizio Frioli, Michele Pedrolli
- *
- * 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.
- *
- * --
- *
- * Please send your questions/suggestions to:
- * {fabrizio.frioli, michele.pedrolli} at studenti dot unitn dot it
- *
- */
-
-package example.bittorrent;
-
-import peersim.core.*;
-import peersim.config.*;
-import peersim.edsim.*;
-import peersim.transport.*;
-
-/**
- * This is the class that implements the BitTorrent module for Peersim
- */
-public class BitTorrent implements EDProtocol {
- /**
- * The size in Megabytes of the file being shared.
- * @config
- */
- private static final String PAR_SIZE="file_size";
- /**
- * The Transport used by the the protocol.
- * @config
- */
- private static final String PAR_TRANSPORT="transport";
- /**
- * The maximum number of neighbor that a node can have.
- * @config
- */
- private static final String PAR_SWARM="max_swarm_size";
- /**
- * The maximum number of peers returned by the tracker when a new
- * set of peers is requested through a <tt>TRACKER</tt> message.
- * @config
- */
- private static final String PAR_PEERSET_SIZE="peerset_size";
- /**
- * Defines how much the network can grow with respect to the <tt>network.size</tt>
- * when {@link NetworkDynamics} is used.
- * @config
- */
- private static final String PAR_MAX_GROWTH="max_growth";
- /**
- * Is the number of requests of the same block sent to different peers.
- * @config
- */
- private static final String PAR_DUP_REQ = "duplicated_requests";
-
- /**
- * KEEP_ALIVE message.
- * @see SimpleEvent#type "Event types"
- */
- private static final int KEEP_ALIVE = 1;
-
- /**
- * CHOKE message.
- * @see SimpleEvent#type "Event types"
- */
- private static final int CHOKE = 2;
-
- /**
- * UNCHOKE message.
- * @see SimpleEvent#type "Event types"
- */
- private static final int UNCHOKE = 3;
-
- /**
- * INTERESTED message.
- * @see SimpleEvent#type "Event types"
- */
- private static final int INTERESTED = 4;
-
- /**
- * NOT_INTERESTED message.
- * @see SimpleEvent#type "Event types"
- */
- private static final int NOT_INTERESTED = 5;
-
- /**
- * HAVE message.
- * @see SimpleEvent#type "Event types"
- */
- private static final int HAVE = 6;
-
- /**
- * BITFIELD message.
- * @see SimpleEvent#type "Event types"
- */
- private static final int BITFIELD = 7;
-
- /**
- * REQUEST message.
- * @see SimpleEvent#type "Event types"
- */
- private static final int REQUEST = 8;
-
- /**
- * PIECE message.
- * @see SimpleEvent#type "Event types"
- */
- private static final int PIECE = 9;
-
- /**
- * CANCEL message.
- * @see SimpleEvent#type "Event types"
- */
- private static final int CANCEL = 10;
-
- /**
- * TRACKER message.
- * @see SimpleEvent#type "Event types"
- */
- private static final int TRACKER = 11;
-
- /**
- * PEERSET message.
- * @see SimpleEvent#type "Event types"
- */
- private static final int PEERSET = 12;
-
- /**
- * CHOKE_TIME event.
- * @see SimpleEvent#type "Event types"
- */
- private static final int CHOKE_TIME = 13;
-
- /**
- * OPTUNCHK_TIME event.
- * @see SimpleEvent#type "Event types"
- */
- private static final int OPTUNCHK_TIME = 14;
-
- /**
- * ANTISNUB_TIME event.
- * @see SimpleEvent#type "Event types"
- */
- private static final int ANTISNUB_TIME = 15;
-
- /**
- * CHECKALIVE_TIME event.
- * @see SimpleEvent#type "Event types"
- */
- private static final int CHECKALIVE_TIME = 16;
-
- /**
- * TRACKERALIVE_TIME event.
- * @see SimpleEvent#type "Event types"
- */
- private static final int TRACKERALIVE_TIME = 17;
-
- /**
- * DOWNLOAD_COMPLETED event.
- * @see SimpleEvent#type "Event types"
- */
- private static final int DOWNLOAD_COMPLETED = 18;
-
- /**
- * The maxium connection speed of the local node.
- */
- int maxBandwidth;
-
- /**
- * Stores the neighbors ordered by ID.
- * @see Element
- */
- private example.bittorrent.Element byPeer[];
-
- /**
- * Contains the neighbors ordered by bandwidth as needed by the unchocking
- * algorithm.
- */
- private example.bittorrent.Element byBandwidth[];
-
- /**
- * The Neighbors list.
- */
- private Neighbor cache[];
-
- /**
- * Reference to the neighbors that unchocked the local node.
- */
- private boolean unchokedBy[];
-
- /**
- * Number of neighbors in the cache. When it decreases under 20, a new peerset
- * is requested to the tracker.
- */
- private int nNodes = 0;
-
- /**
- * Maximum number of nodes in the network.
- */
- private int nMaxNodes;
-
- /**
- * The status of the local peer. 0 means that the current peer is a leecher, 1 a seeder.
- */
- private int peerStatus;
-
- /**
- * Defines how much the network can grow with respect to the <tt>network.size</tt>
- * when {@link NetworkDynamics} is used.
- */
- public int maxGrowth;
-
- /**
- * File status of the local node. Contains the blocks owned by the local node.
- */
- private int status[];
-
- /**
- * Current number of Bitfield request sent. It must be taken into account
- * before sending another one.
- */
- private int nBitfieldSent = 0;
-
- /**
- * Current number of pieces in upload from the local peer.
- */
- public int nPiecesUp = 0;
- /**
- * Current number of pieces in download to the local peer.
- */
- public int nPiecesDown = 0;
-
- /**
- * Current number of piece completed.
- */
- private int nPieceCompleted = 0;
-
- /**
- * Current downloading piece ID, the previous lastInterested piece.
- */
- int currentPiece = -1;
-
- /**
- * Used to compute the average download rates in choking algorithm. Stores the
- * number of <tt>CHOKE</tt> events.
- */
- int n_choke_time = 0;
-
- /**
- * Used to send the <tt>TRACKER</tt> message when the local node has 20 neighbors
- * for the first time.
- */
- boolean lock = false;
-
- /**
- * Number of peers interested to my pieces.
- */
- int numInterestedPeers = 0;
-
- /**
- * Last piece for which the local node sent an <tt>INTERESTED</tt> message.
- */
- int lastInterested = -1;
-
- /**
- * The status of the current piece in download. Length 16, every time the local node
- * receives a PIECE message, it updates the corrisponding block's cell. The cell
- * contains the ID for that block of that piece. If an already owned
- * block is received this is discarded.
- */
- private int pieceStatus[];
-
- /**
- * Length of the file. Stored as number of pieces (256KB each one).
- */
- int nPieces;
-
- /**
- * Contains the neighbors's status of the file. Every row represents a
- * node and every a cell has value O if the neighbor doesn't
- * have the piece, 1 otherwise. It has {@link #swarmSize} rows and {@link #nPieces}
- * columns.
- */
- int [][]swarm;
-
- /**
- * The summation of the swarm's rows. Calculated every time a {@link #BITFIELD} message
- * is received and updated every time HAVE message is received.
- */
- int rarestPieceSet[];
-
- /**
- * The five pending block requests.
- */
- int pendingRequest[];
-
- /**
- * The maximum swarm size (default is 80)
- */
- int swarmSize;
-
- /**
- * The size of the peerset. This is the number of "friends" nodes
- * sent from the tracker to each new node (default: 50)
- */
- int peersetSize;
-
- /**
- * The ID of the current node
- */
- private long thisNodeID;
-
- /**
- * Number of duplicated requests as specified in the configuration file.
- * @see BitTorrent#PAR_DUP_REQ
- */
- private int numberOfDuplicatedRequests;
-
- /**
- * The queue where the requests to serve are stored.
- * The default dimension of the queue is 20.
- */
- Queue requestToServe = null;
-
- /**
- * The queue where the out of sequence incoming pieces are stored
- * waiting for the right moment to be processed.
- * The default dimension of the queue is 100.
- */
- Queue incomingPieces = null;
-
- /**
- * The Transport ID.
- * @see BitTorrent#PAR_TRANSPORT
- */
- int tid;
-
- /**
- * The reference to the tracker node. If equals to <tt>null</tt>, the local
- * node is the tracker.
- */
- private Node tracker = null;
-
- /**
- * The default constructor. Reads the configuration file and initializes the
- * configuration parameters.
- * @param prefix the component prefix declared in the configuration file
- */
- public BitTorrent(String prefix){ // Used for the tracker's protocol
- tid = Configuration.getPid(prefix+"."+PAR_TRANSPORT);
- nPieces = (int)((Configuration.getInt(prefix+"."+PAR_SIZE))*1000000/256000);
- swarmSize = (int)Configuration.getInt(prefix+"."+PAR_SWARM);
- peersetSize = (int)Configuration.getInt(prefix+"."+PAR_PEERSET_SIZE);
- numberOfDuplicatedRequests = (int)Configuration.getInt(prefix+"."+PAR_DUP_REQ);
- maxGrowth = (int)Configuration.getInt(prefix+"."+PAR_MAX_GROWTH);
- nMaxNodes = Network.getCapacity()-1;
- }
-
- /**
- * Gets the reference to the tracker node.
- * @return the reference to the tracker
- */
- public Node getTracker(){
- return tracker;
- }
-
- /**
- * Gets the number of neighbors currently stored in the cache of the local node.
- * @return the number of neighbors in the cache
- */
- public int getNNodes(){
- return this.nNodes;
- }
-
- /**
- * Sets the reference to the tracker node.
- * @param t the tracker node
- */
- public void setTracker(Node t){
- tracker = t;
- }
-
- /**
- * Sets the ID of the local node.
- * @param id the ID of the node
- */
- public void setThisNodeID(long id) {
- this.thisNodeID = id;
- }
-
- /**
- * Gets the ID of the local node.
- * @return the ID of the local node
- */
- public long getThisNodeID(){
- return this.thisNodeID;
- }
-
- /**
- * Gets the file status of the local node.
- * @return the file status of the local node
- */
- public int[] getFileStatus(){
- return this.status;
- }
-
- /**
- * Initializes the tracker node. This method
- * only performs the initialization of the tracker's cache.
- */
- public void initializeTracker() {
- cache = new Neighbor[nMaxNodes+maxGrowth];
- for(int i=0; i<nMaxNodes+maxGrowth; i++){
- cache[i]= new Neighbor();
- }
- }
-
- /**
- * <p>Checks the number of neighbors and if it is equal to 20
- * sends a TRACKER messages to the tracker, asking for a new
- * peer set.</p>
- *
- * <p>This method *must* be called after every call of {@link #removeNeighbor}
- * in {@link #processEvent}.
- * </p>
- */
- private void processNeighborListSize(Node node, int pid) {
- if (nNodes==20) {
- Object ev;
- long latency;
- ev = new SimpleMsg(TRACKER, node);
- Node tracker = ((BitTorrent)node.getProtocol(pid)).tracker;
- if(tracker != null){
-// latency = ((Transport)node.getProtocol(tid)).getLatency(node, tracker);
-// EDSimulator.add(latency,ev,tracker,pid);
- ((Transport) node.getProtocol(tid)).send(node, tracker, ev, pid);
- }
- }
- }
-
- /**
- * The standard method that processes incoming events.
- * @param node reference to the local node for which the event is going to be processed
- * @param pid BitTorrent's protocol id
- * @param event the event to process
- */
- public void processEvent(Node node, int pid, Object event){
-
- Object ev;
- long latency;
- switch(((SimpleEvent)event).getType()){
-
- case KEEP_ALIVE: // 1
- {
- Node sender = ((IntMsg)event).getSender();
- int isResponse = ((IntMsg)event).getInt();
- //System.out.println("process, keep_alive: sender is "+sender.getID()+", local is "+node.getID());
- Element e = search(sender.getID());
- if(e!= null){ //if I know the sender
- cache[e.peer].isAlive();
- if(isResponse==0 && alive(sender)){
- Object msg = new IntMsg(KEEP_ALIVE,node,1,0);
-// latency = ((Transport)node.getProtocol(tid)).getLatency(node, sender);
-// EDSimulator.add(latency,msg,sender,pid);
- ((Transport) node.getProtocol(tid)).send(node, sender, msg, pid);
- cache[e.peer].justSent();
- }
- }
- else{
- System.err.println("despite it should never happen, it happened");
- ev = new BitfieldMsg(BITFIELD, true, false, node, status, nPieces);
-// latency = ((Transport)node.getProtocol(tid)).getLatency(node,sender);
-// EDSimulator.add(latency,ev,sender,pid);
- ((Transport) node.getProtocol(tid)).send(node, sender, ev, pid);
- nBitfieldSent++;
- }
-
- };break;
-
- case CHOKE: // 2, CHOKE message.
- {
- Node sender = ((SimpleMsg)event).getSender();
- //System.out.println("process, choke: sender is "+sender.getID()+", local is "+node.getID());
- Element e = search(sender.getID());
- if(e!= null){ //if I know the sender
- cache[e.peer].isAlive();
- unchokedBy[e.peer]= false; // I'm choked by it
- }
- else{
- System.err.println("despite it should never happen, it happened");
- ev = new BitfieldMsg(BITFIELD, true, false, node, status, nPieces);
-// latency = ((Transport)node.getProtocol(tid)).getLatency(node,sender);
-// EDSimulator.add(latency,ev,sender,pid);
- ((Transport) node.getProtocol(tid)).send(node, sender, ev, pid);
- nBitfieldSent++;
- }
- };break;
-
- case UNCHOKE: // 3, UNCHOKE message.
- {
- Node sender = ((SimpleMsg)event).getSender();
- //System.out.println("process, unchoke: sender is "+sender.getID()+", local is "+node.getID());
- Element e = search(sender.getID());
- if(e != null){ // If I know the sender
- int senderIndex = e.peer;
- cache[senderIndex].isAlive();
- /* I send to it some of the pending requests not yet satisfied. */
- int t = numberOfDuplicatedRequests;
- for(int i=4;i>=0 && t>0;i--){
- if(pendingRequest[i]==-1)
- break;
- if(alive(cache[senderIndex].node) && swarm[senderIndex][decode(pendingRequest[i],0)]==1){ //If the sender has that piece
- ev = new IntMsg(REQUEST, node,pendingRequest[i],0);
-// latency = ((Transport)node.getProtocol(tid)).getLatency(node,sender);
-// EDSimulator.add(latency,ev, sender,pid);
- ((Transport) node.getProtocol(tid)).send(node, sender, ev, pid);
- cache[senderIndex].justSent();
- }
- if(!alive(cache[senderIndex].node)){
- System.out.println("unchoke1 rm neigh "+ cache[i].node.getID() );
- removeNeighbor(cache[senderIndex].node);
- processNeighborListSize(node,pid);
- return;
- }
- t--;
- }
- // I request missing blocks to fill the queue
- int block = getBlock();
- int piece;
- while(block != -2){ //while still available request to send
- if(block < 0){ // No more block to request for the current piece
- piece = getPiece();
- if(piece == -1){ // no more piece to request
- break;
- }
- for(int j=0; j<swarmSize; j++){// send the interested message to those
- // nodes which have that piece
- lastInterested = piece;
- if(alive(cache[j].node) && swarm[j][piece]==1){
- ev = new IntMsg(INTERESTED, node, lastInterested,0);
-// latency = ((Transport)node.getProtocol(tid)).getLatency(node,cache[j].node);
-// EDSimulator.add(latency,ev,cache[j].node,pid);
- ((Transport) node.getProtocol(tid)).send(node, cache[j].node, ev, pid);
- cache[j].justSent();
- }
-
- if(!alive(cache[j].node)){
- //System.out.println("unchoke2 rm neigh "+ cache[j].node.getID() );
- removeNeighbor(cache[j].node);
- processNeighborListSize(node,pid);
- }
- }
- block = getBlock();
- }
- else{ // block value referred to a real block
- if(alive(cache[senderIndex].node) && swarm[senderIndex][decode(block,0)]==1 && addRequest(block)){ // The sender has that block
- ev = new IntMsg(REQUEST, node, block,0);
-// latency = ((Transport)node.getProtocol(tid)).getLatency(node,sender);
-// EDSimulator.add(latency,ev,sender,pid);
- ((Transport) node.getProtocol(tid)).send(node, sender, ev, pid);
-
- cache[senderIndex].justSent();
- }
- else{
- if(!alive(cache[senderIndex].node)){
- System.out.println("unchoke3 rm neigh "+ cache[senderIndex].node.getID() );
- removeNeighbor(cache[senderIndex].node);
- processNeighborListSize(node,pid);
- }
- return;
- }
- block = getBlock();
- }
- }
- unchokedBy[senderIndex] = true; // I add the sender to the list
- }
- else // It should never happen.
- {
- System.err.println("despite it should never happen, it happened");
- for(int i=0; i<swarmSize; i++)
- if(cache[i].node !=null)
- System.err.println(cache[i].node.getID());
- ev = new BitfieldMsg(BITFIELD, true, false, node, status, nPieces);
-// latency = ((Transport)node.getProtocol(tid)).getLatency(node,sender);
-// EDSimulator.add(latency,ev,sender,pid);
- ((Transport) node.getProtocol(tid)).send(node, sender, ev, pid);
- nBitfieldSent++;
- }
- };break;
-
- case INTERESTED: // 4, INTERESTED message.
- {
- numInterestedPeers++;
- Node sender = ((IntMsg)event).getSender();
- //System.out.println("process, interested: sender is "+sender.getID()+", local is "+node.getID());
- int value = ((IntMsg)event).getInt();
- Element e = search(sender.getID());
- if(e!=null){
- cache[e.peer].isAlive();
- cache[e.peer].interested = value;
- }
- else{
- System.err.println("despite it should never happen, it happened");
- ev = new BitfieldMsg(BITFIELD, true, false, node, status, nPieces);
-// latency = ((Transport)node.getProtocol(tid)).getLatency(node,sender);
-// EDSimulator.add(latency,ev,sender,pid);
- ((Transport) node.getProtocol(tid)).send(node, sender, ev, pid);
- nBitfieldSent++;
- }
-
- }; break;
-
- case NOT_INTERESTED: // 5, NOT_INTERESTED message.
- {
- numInterestedPeers--;
- Node sender = ((IntMsg)event).getSender();
- //System.out.println("process, not_interested: sender is "+sender.getID()+", local is "+node.getID());
- int value = ((IntMsg)event).getInt();
- Element e = search(sender.getID());
- if(e!=null){
- cache[e.peer].isAlive();
- if(cache[e.peer].interested == value)
- cache[e.peer].interested = -1; // not interested
- }
- }; break;
-
- case HAVE: // 6, HAVE message.
- {
- Node sender = ((IntMsg)event).getSender();
- //System.out.println("process, have: sender is "+sender.getID()+", local is "+node.getID());
- int piece = ((IntMsg)event).getInt();
- Element e = search(sender.getID());
- if(e!=null){
- cache[e.peer].isAlive();
- swarm[e.peer][piece]=1;
- rarestPieceSet[piece]++;
- boolean isSeeder = true;
- for(int i=0; i<nPieces; i++){
- isSeeder = isSeeder && (swarm[e.peer][i]==1);
- }
- e.isSeeder = isSeeder;
- }
- else{
- System.err.println("despite it should never happen, it happened");
- ev = new BitfieldMsg(BITFIELD, true, false, node, status, nPieces);
-// latency = ((Transport)node.getProtocol(tid)).getLatency(node,sender);
-// EDSimulator.add(latency,ev,sender,pid);
- ((Transport) node.getProtocol(tid)).send(node, sender, ev, pid);
- nBitfieldSent++;
- }
- }; break;
-
- case BITFIELD: // 7, BITFIELD message
- {
- Node sender = ((BitfieldMsg)event).getSender();
- int []fileStatus = ((BitfieldMsg)event).getArray();
- /*Response with NACK*/
- if(!((BitfieldMsg)event).isRequest && !((BitfieldMsg)event).ack){
- Element e = search(sender.getID());
- if(e == null) // if is a response with nack that follows a request
- nBitfieldSent--;
- // otherwise is a response with ack that follows a duplicate
- // insertion attempt
- //System.out.println("process, bitfield_resp_nack: sender is "+sender.getID()+", local is "+node.getID());
- return;
- }
- /*Request with NACK*/
- if(((BitfieldMsg)event).isRequest && !((BitfieldMsg)event).ack){
- //System.out.println("process, bitfield_req_nack: sender is "+sender.getID()+", local is "+node.getID());
- if(alive(sender)){
- Element e = search(sender.getID());
- ev = new BitfieldMsg(BITFIELD, false, true, node, status, nPieces); //response with ack
-// latency = ((Transport)node.getProtocol(tid)).getLatency(node,sender);
-// EDSimulator.add(latency,ev,sender,pid);
- ((Transport) node.getProtocol(tid)).send(node, sender, ev, pid);
- cache[e.peer].justSent();
- }
- }
- /*Response with ACK*/
- if(!((BitfieldMsg)event).isRequest && ((BitfieldMsg)event).ack){
- nBitfieldSent--;
- //System.out.println("process, bitfield_resp_ack: sender is "+sender.getID()+", local is "+node.getID());
- if(alive(sender)){
- if(addNeighbor(sender)){
- Element e = search(sender.getID());
- cache[e.peer].isAlive();
- swarm[e.peer] = fileStatus;
- boolean isSeeder = true;
- for(int i=0; i<nPieces; i++){
- rarestPieceSet[i]+= fileStatus[i];
- isSeeder = isSeeder && (fileStatus[i]==1);
- }
- e.isSeeder = isSeeder;
-
- if(nNodes==10 && !lock){ // I begin to request pieces
- lock = true;
- int piece = getPiece();
- if(piece == -1)
- return;
- lastInterested = piece;
- currentPiece = lastInterested;
- ev = new IntMsg(INTERESTED, node, lastInterested,0);
- for(int i=0; i<swarmSize; i++){// send the interested message to those
- // nodes which have that piece
- if(alive(cache[i].node) && swarm[i][piece]==1){
-// latency = ((Transport)node.getProtocol(tid)).getLatency(node,cache[i].node);
-// EDSimulator.add(latency,ev,cache[i].node,pid);
- ((Transport) node.getProtocol(tid)).send(node, cache[i].node, ev, pid);
- cache[i].justSent();
- }
- }
-
- }
-
- }
- }
- else
- System.out.println("Sender "+sender.getID()+" not alive");
- }
- /*Request with ACK*/
- if(((BitfieldMsg)event).isRequest && ((BitfieldMsg)event).ack){
- //System.out.println("process, bitfield_req_ack: sender is "+sender.getID()+", local is "+node.getID());
- if(alive(sender)){
- if(addNeighbor(sender)){
- Element e = search(sender.getID());
- cache[e.peer].isAlive();
- swarm[e.peer] = fileStatus;
- boolean isSeeder = true;
- for(int i=0; i<nPieces; i++){
- rarestPieceSet[i]+= fileStatus[i]; // I update the rarestPieceSet with the pieces of the new node
- isSeeder = isSeeder && (fileStatus[i]==1); // I check if the new node is a seeder
- }
- e.isSeeder = isSeeder;
- ev = new BitfieldMsg(BITFIELD, false, true, node, status, nPieces); //response with ack
-// latency = ((Transport)node.getProtocol(tid)).getLatency(node,sender);
-// EDSimulator.add(latency,ev,sender,pid);
- ((Transport) node.getProtocol(tid)).send(node, sender, ev, pid);
- cache[e.peer].justSent();
- if(nNodes==10 && !lock){ // I begin to request pieces
- int piece = getPiece();
- if(piece == -1)
- return;
- lastInterested = piece;
- currentPiece = lastInterested;
- ev = new IntMsg(INTERESTED, node, lastInterested,0);
- for(int i=0; i<swarmSize; i++){// send the interested message to those
- // nodes which have that piece
- if(alive(cache[i].node) && swarm[i][piece]==1){
-// latency = ((Transport)node.getProtocol(tid)).getLatency(node,cache[i].node);
-// EDSimulator.add(latency,ev,cache[i].node,pid);
- ((Transport) node.getProtocol(tid)).send(node, cache[i].node, ev, pid);
- cache[i].justSent();
- }
- }
-
- }
- }
- else {
- Element e;
- if((e = search(sender.getID()))!=null){ // The sender was already in the cache
- cache[e.peer].isAlive();
- ev = new BitfieldMsg(BITFIELD, false, true, node, status, nPieces); //response with ack
-// latency = ((Transport)node.getProtocol(tid)).getLatency(node,sender);
-// EDSimulator.add(latency,ev,sender,pid);
- ((Transport) node.getProtocol(tid)).send(node, sender, ev, pid);
- cache[e.peer].justSent();
- }
- else{ // Was not be possible add the sender (nBitfield+nNodes > swarmSize)
- ev = new BitfieldMsg(BITFIELD, false, false, node, status, nPieces); //response with nack
-// latency = ((Transport)node.getProtocol(tid)).getLatency(node,sender);
-// EDSimulator.add(latency,ev,sender,pid);
- ((Transport) node.getProtocol(tid)).send(node, sender, ev, pid);
- }
- }
-
- }
- else
- System.out.println("Sender "+sender.getID()+" not alive");
- }
- };break;
-
- case REQUEST: // 8, REQUEST message.
- {
- Object evnt;
- Node sender = ((IntMsg)event).getSender();
- int value = ((IntMsg)event).getInt();
- Element e;
- BitTorrent senderP;
- int remoteRate;
- int localRate;
- int bandwidth;
- int downloadTime;
-
- e = search(sender.getID());
- if (e==null)
- return;
- cache[e.peer].isAlive();
-
- requestToServe.enqueue(value, sender);
-
- /*I serve the enqueued requests until 10 uploding pieces or an empty queue*/
- while(!requestToServe.empty() && nPiecesUp <10){
- Request req = requestToServe.dequeue();
- e = search(req.sender.getID());
- if(e!=null && alive(req.sender)){
-// ev = new IntMsg(PIECE, node, req.id);
- nPiecesUp++;
- e.valueUP++;
- senderP = ((BitTorrent)req.sender.getProtocol(pid));
- senderP.nPiecesDown++;
- remoteRate = senderP.maxBandwidth/(senderP.nPiecesUp + senderP.nPiecesDown);
- localRate = maxBandwidth/(nPiecesUp + nPiecesDown);
- bandwidth = Math.min(remoteRate, localRate);
- downloadTime = ((16*8)/(bandwidth))*1000; // in milliseconds
-
- ev = new IntMsg(PIECE, node, req.id, 16*8 * 1024);
- ((Transport) node.getProtocol(tid)).send(node, req.sender, ev, pid);
-
-// latency = ((Transport)node.getProtocol(tid)).getLatency(node,req.sender);
-// EDSimulator.add(latency+downloadTime,ev,req.sender,pid);
- cache[e.peer].justSent();
-
- /*I send to me an event to indicate that the download is completed.
- This prevent that, when the receiver death occurres, my value nPiecesUp
- doesn't decrease.*/
- evnt = new SimpleMsg(DOWNLOAD_COMPLETED, req.sender);
-// EDSimulator.add(latency+downloadTime,evnt,node,pid);
- ((Transport) node.getProtocol(tid)).send(node, node, evnt, pid);
- }
- }
- }; break;
-
- case PIECE: // 9, PIECE message.
- {
- Node sender = ((IntMsg)event).getSender();
- /* Set the correct value for the local uploading and remote
- downloading number of pieces */
- nPiecesDown--;
-
- if(peerStatus == 1)// To save CPU cycles
- return;
- //System.out.println("process, piece: sender is "+sender.getID()+", local is "+node.getID());
- Element e = search(sender.getID());
-
- if(e==null){ //I can't accept a piece not wait
- return;
- }
- e.valueDOWN++;
-
- cache[e.peer].isAlive();
-
- int value = ((IntMsg)event).getInt();
- int piece = decode(value,0);
- int block = decode(value,1);
- /* If the block has not been already downloaded and it belongs to
- the current downloading piece.*/
- if(piece == currentPiece && decode(pieceStatus[block],0)!= piece){
- pieceStatus[block] = value;
- status[piece]++;
- removeRequest(value);
- requestNextBlocks(node, pid, e.peer);
-
- }else{ // Either a future piece or an owned piece
- if(piece!=currentPiece && status[piece]!=16){ // Piece not owned, will be considered later
- incomingPieces.enqueue(value, sender);
- }
-
- }
- ev = new IntMsg(CANCEL, node, value,0);
- /* I send a CANCEL to all nodes to which I previously requested the block*/
- for(int i=0; i<swarmSize; i++){
- if(alive(cache[i].node) && unchokedBy[i]==true && swarm[i][decode(block,0)]==1 && cache[i].node != sender){
-// latency = ((Transport)node.getProtocol(tid)).getLatency(node,cache[i].node);
-// EDSimulator.add(latency,ev,cache[i].node,pid);
- ((Transport) node.getProtocol(tid)).send(node, cache[i].node, ev, pid);
- cache[i].justSent();
- }
- }
-
- if(status[currentPiece]==16){ // if piece completed, I change the currentPiece to the next wanted
- nPieceCompleted++;
- ev = new IntMsg(HAVE, node, currentPiece,0);
- for(int i=0; i<swarmSize; i++){ // I send the HAVE for the piece
- if(alive(cache[i].node)){
-// latency = ((Transport)node.getProtocol(tid)).getLatency(node,cache[i].node);
-// EDSimulator.add(latency,ev,cache[i].node,pid);
- ((Transport) node.getProtocol(tid)).send(node, cache[i].node, ev, pid);
- cache[i].justSent();
- }
- if(!alive(cache[i].node)){
- //System.out.println("piece3 rm neigh "+ cache[i].node.getID() );
- removeNeighbor(cache[i].node);
- processNeighborListSize(node,pid);
- }
- }
- ev = new IntMsg(NOT_INTERESTED, node, currentPiece,0);
- for(int i=0; i<swarmSize; i++){ // I send the NOT_INTERESTED to which peer I sent an INTERESTED
- if(swarm[i][piece]==1 && alive(cache[i].node)){
-// latency = ((Transport)node.getProtocol(tid)).getLatency(node,cache[i].node);
-// EDSimulator.add(latency,ev,cache[i].node,pid);
- ((Transport) node.getProtocol(tid)).send(node, cache[i].node, ev, pid);
- cache[i].justSent();
- }
- if(!alive(cache[i].node)){
- //System.out.println("piece4 rm neigh "+ cache[i].node.getID() );
- removeNeighbor(cache[i].node);
- processNeighborListSize(node,pid);
- }
- }
- if(nPieceCompleted == nPieces){
- System.out.println("FILE COMPLETED for peer "+node.getID());
- this.peerStatus = 1;
- }
-
- /* I set the currentPiece to the lastInterested. Then I extract
- the queued received blocks
- */
-
- currentPiece = lastInterested;
- int m = incomingPieces.dim;
- while(m > 0){ // I process the queue
- m--;
- Request temp = incomingPieces.dequeue();
- int p = decode(temp.id,0); // piece id
- int b = decode(temp.id,1); // block id
- Element s = search(temp.sender.getID());
- if(s==null) // if the node that sent the block in the queue is dead
- continue;
- if(p==currentPiece && decode(pieceStatus[b],0)!= p){
- pieceStatus[b] = temp.id;
- status[p]++;
- removeRequest(temp.id);
- requestNextBlocks(node, pid, s.peer);
- }
- else{ // The piece not currently desired will be moved to the tail
- if(p!= currentPiece) // If not a duplicate block but belongs to another piece
- incomingPieces.enqueue(temp.id,temp.sender);
- else // duplicate block
- requestNextBlocks(node, pid, s.peer);
- }
- }
- }
- }; break;
-
- case CANCEL:
- {
- Node sender = ((IntMsg)event).getSender();
- int value = ((IntMsg)event).getInt();
- requestToServe.remove(sender, value);
- };break;
-
- case PEERSET: // PEERSET message
- {
- Node sender = ((PeerSetMsg)event).getSender();
- //System.out.println("process, peerset: sender is "+sender.getID()+", local is "+node.getID());
- Neighbor n[] = ((PeerSetMsg)event).getPeerSet();
-
- for(int i=0; i<peersetSize; i++){
- if( n[i]!=null && alive(n[i].node) && search(n[i].node.getID())==null && nNodes+nBitfieldSent <swarmSize-2) {
- ev = new BitfieldMsg(BITFIELD, true, true, node, status, nPieces);
-// latency = ((Transport)node.getProtocol(tid)).getLatency(node,n[i].node);
-// EDSimulator.add(latency,ev,n[i].node,pid);
- ((Transport) node.getProtocol(tid)).send(node, n[i].node, ev, pid);
-
- nBitfieldSent++;
- // Here I should call the Neighbor.justSent(), but here
- // the node is not yet in the cache.
- }
- }
- }; break;
-
- case TRACKER: // TRACKER message
- {
-
- int j=0;
- Node sender = ((SimpleMsg)event).getSender();
- //System.out.println("process, tracker: sender is "+sender.getID()+", local is "+node.getID());
- if(!alive(sender))
- return;
- Neighbor tmp[] = new Neighbor[peersetSize];
- int k=0;
- if(nNodes <= peersetSize){
- for(int i=0; i< nMaxNodes+maxGrowth; i++){
- if(cache[i].node != null && cache[i].node.getID()!= sender.getID()){
- tmp[k]=cache[i];
- k++;
- }
- }
- ev = new PeerSetMsg(PEERSET, tmp, node);
-// latency = ((Transport)node.getProtocol(tid)).getLatency(node, sender);
-// EDSimulator.add(latency,ev,sender,pid);
- ((Transport) node.getProtocol(tid)).send(node,sender, ev, pid);
- return;
- }
-
- while(j < peersetSize){
- int i = CommonState.r.nextInt(nMaxNodes+maxGrowth);
- for (int z=0; z<j; z++){
- if(cache[i].node==null || tmp[z].node.getID() == cache[i].node.getID() || cache[i].node.getID() == sender.getID()){
- z=0;
- i= CommonState.r.nextInt(nMaxNodes+maxGrowth);
- }
- }
- if(cache[i].node != null){
- tmp[j] = cache[i];
- j++;
- }
- }
- ev = new PeerSetMsg(PEERSET, tmp, node);
-// latency = ((Transport)node.getProtocol(tid)).getLatency(node, sender);
-// EDSimulator.add(latency,ev,sender,pid);
- ((Transport) node.getProtocol(tid)).send(node,sender, ev, pid);
- }; break;
-
- case CHOKE_TIME: //Every 10 secs.
- {
- n_choke_time++;
-
- ev = new SimpleEvent(CHOKE_TIME);
- EDSimulator.add(10000,ev,node,pid);
- int j=0;
- /*I copy the interested nodes in the byBandwidth array*/
- for(int i=0;i< swarmSize && byPeer[i].peer != -1; i++){
- if(cache[byPeer[i].peer].interested > 0){
- byBandwidth[j]=byPeer[i]; //shallow copy
- j++;
- }
- }
-
- /*It ensures that in the next 20sec, if there are less nodes interested
- than now, those in surplus will not be ordered. */
- for(;j<swarmSize;j++){
- byBandwidth[j]=null;
- }
- sortByBandwidth();
- int optimistic = 3;
- int luckies[] = new int[3];
- try{ // It takes the first three neighbors
- luckies[0] = byBandwidth[0].peer;
- optimistic--;
- luckies[1] = byBandwidth[1].peer;
- optimistic--;
- luckies[2] = byBandwidth[2].peer;
- }
- catch(NullPointerException e){ // If not enough peer in byBandwidth it chooses the other romdomly
- for(int z = optimistic; z>0;z--){
- int lucky = CommonState.r.nextInt(nNodes);
- while(cache[byPeer[lucky].peer].status ==1 && alive(cache[byPeer[lucky].peer].node) &&
- cache[byPeer[lucky].peer].interested == 0)// until the lucky peer is already unchoked or not interested
- lucky = CommonState.r.nextInt(nNodes);
- luckies[3-z]= byPeer[lucky].peer;
- }
- }
- for(int i=0; i<swarmSize; i++){ // I perform the chokes and the unchokes
- if((i==luckies[0] || i==luckies[1] || i==luckies[2]) && alive(cache[i].node) && cache[i].status != 2){ //the unchokes
- cache[i].status = 1;
- ev = new SimpleMsg(UNCHOKE, node);
-// latency = ((Transport)node.getProtocol(tid)).getLatency(node, cache[i].node);
-// EDSimulator.add(latency,ev,cache[i].node,pid);
- ((Transport) node.getProtocol(tid)).send(node,cache[i].node, ev, pid);
- cache[i].justSent();
- //System.out.println("average time, unchoked: "+cache[i].node.getID());
- }
- else{ // the chokes
- if(alive(cache[i].node) && (cache[i].status == 1 || cache[i].status == 2)){
- cache[i].status = 0;
- ev = new SimpleMsg(CHOKE, node);
-// latency = ((Transport)node.getProtocol(tid)).getLatency(node, cache[i].node);
-// EDSimulator.add(latency,ev,cache[i].node,pid);
- ((Transport) node.getProtocol(tid)).send(node,cache[i].node, ev, pid);
- cache[i].justSent();
- }
- }
- }
-
- if(n_choke_time%2==0){ //every 20 secs. Used in computing the average download rates
- for(int i=0; i<nNodes; i++){
- if(this.peerStatus == 0){ // I'm a leeacher
- byPeer[i].head20 = byPeer[i].valueDOWN;
- }
- else{
- byPeer[i].head20 = byPeer[i].valueUP;
- }
- }
- }
- }; break;
-
- case OPTUNCHK_TIME:
- {
-
- //System.out.println("process, optunchk_time");
-
- ev = new SimpleEvent(OPTUNCHK_TIME);
- EDSimulator.add(30000,ev,node,pid);
- int lucky = CommonState.r.nextInt(nNodes);
- while(cache[byPeer[lucky].peer].status ==1)// until the lucky peer is already unchoked
- lucky = CommonState.r.nextInt(nNodes);
- if(!alive(cache[byPeer[lucky].peer].node))
- return;
- cache[byPeer[lucky].peer].status = 1;
- Object msg = new SimpleMsg(UNCHOKE,node);
-// latency = ((Transport)node.getProtocol(tid)).getLatency(node, cache[byPeer[lucky].peer].node);
-// EDSimulator.add(latency,msg,cache[byPeer[lucky].peer].node,pid);
- ((Transport) node.getProtocol(tid)).send(node,cache[byPeer[lucky].peer].node, msg, pid);
- cache[byPeer[lucky].peer].justSent();
- }; break;
-
- case ANTISNUB_TIME:
- {
- if(this.peerStatus == 1) // I'm a seeder, I don't update the event
- return;
- //System.out.println("process, antisnub_time");
- for(int i=0; i<nNodes; i++){
- if(byPeer[i].valueDOWN >0 && (byPeer[i].valueDOWN - byPeer[i].head60)==0){// No blocks downloaded in 1 min
- cache[byPeer[i].peer].status = 2; // I'm snubbed by it
- }
- byPeer[i].head60 = byPeer[i].valueDOWN;
- }
- ev = new SimpleEvent(ANTISNUB_TIME);
- EDSimulator.add(60000,ev,node,pid);
- long time = CommonState.getTime();
- }; break;
-
- case CHECKALIVE_TIME:
- {
-
- //System.out.println("process, checkalive_time");
-
- long now = CommonState.getTime();
- for(int i=0; i<swarmSize; i++){
- /*If are at least 2 minutes (plus 1 sec of tolerance) that
- I don't send anything to it.*/
- if(alive(cache[i].node) && (cache[i].lastSent < (now-121000))){
- Object msg = new IntMsg(KEEP_ALIVE,node,0,0);
-// latency = ((Transport)node.getProtocol(tid)).getLatency(node, cache[i].node);
-// EDSimulator.add(latency,msg,cache[i].node,pid);
- ((Transport) node.getProtocol(tid)).send(node,cache[i].node, msg, pid);
- cache[i].justSent();
- }
- /*If are at least 2 minutes (plus 1 sec of tolerance) that I don't
- receive anything from it though I sent a keepalive 2 minutes ago*/
- else{
- if(cache[i].lastSeen <(now-121000) && cache[i].node != null && cache[i].lastSent < (now-121000)){
- System.out.println("process, checkalive_time, rm neigh " + cache[i].node.getID());
- if(cache[i].node.getIndex() != -1){
- System.out.println("This should never happen: I remove a node that is not effectively died");
- }
- removeNeighbor(cache[i].node);
- processNeighborListSize(node,pid);
- }
- }
- }
- ev = new SimpleEvent(CHECKALIVE_TIME);
- EDSimulator.add(120000,ev,node,pid);
- }; break;
-
- case TRACKERALIVE_TIME:
- {
- //System.out.println("process, trackeralive_time");
- if(alive(tracker)){
- ev = new SimpleEvent(TRACKERALIVE_TIME);
- EDSimulator.add(1800000,ev,node,pid);
- }
- else
- tracker=null;
-
- }; break;
-
- case DOWNLOAD_COMPLETED:
- {
- nPiecesUp--;
- }; break;
-
- }
- }
-
- /**
- * Given a piece index and a block index it encodes them in an unique integer value.
- * @param piece the index of the piece to encode.
- * @param block the index of the block to encode.
- * @return the encoding of the piece and the block indexes.
- */
- private int encode(int piece, int block){
- return (piece*100)+block;
-
- }
- /**
- * Returns either the piece or the block that contained in the <tt>value</tt> depending
- * on <tt>part</tt>: 0 means the piece value, 1 the block value.
- * @param value the ID of the block to decode.
- * @param part the information to extract from <tt>value</tt>. 0 means the piece index, 1 the block index.
- * @return the piece or the block index depending about the value of <tt>part</tt>
- */
- private int decode(int value, int part){
- if (value==-1) // Not a true value to decode
- return -1;
- if(part == 0) // I'm interested to the piece
- return value/100;
- else // I'm interested to the block
- return value%100;
- }
-
- /**
- * Used by {@link NodeInitializer#choosePieces(int, BitTorrent) NodeInitializer} to set
- * the number of piece completed from the beginning in according with
- * the distribution in the configuration file.
- * @param number the number of piece completed
- */
- public void setCompleted(int number){
- this.nPieceCompleted = number;
- }
-
- /**
- * Sets the status (the set of blocks) of the file for the current node.
- * Note that a piece is considered <i>completed</i> if the number
- * of downloaded blocks is 16.
- * @param index The index of the piece
- * @param value Number of blocks downloaded for the piece index.
- */
- public void setStatus(int index, int value){
- status[index]=value;
- }
-
- /**
- * Sets the status of the local node.
- * @param status The status of the node: 1 means seeder, 0 leecher
- */
- public void setPeerStatus(int status){
- this.peerStatus = status;
- }
-
- /**
- * Gets the status of the local node.
- * @return The status of the local node: 1 means seeder, 0 leecher
- */
- public int getPeerStatus(){
- return peerStatus;
- }
-
- /**
- * Gets the number of blocks for a given piece owned by the local node.
- * @param index The index of the piece
- * @return Number of blocks downloaded for the piece index
- */
- public int getStatus(int index){
- return status[index];
- }
-
- /**
- * Sets the maximum bandwdith for the local node.
- * @param value The value of bandwidth in Kbps
- */
- public void setBandwidth(int value){
- maxBandwidth = value;
- }
-
- /**
- * Checks if a node is still alive in the simulated network.
- * @param node The node to check
- * @return true if the node <tt>node</tt> is up, false otherwise
- * @see peersim.core.GeneralNode#isUp
- */
- public boolean alive(Node node){
- if(node == null)
- return false;
- else
- return node.isUp();
- }
-
- /**
- * Adds a neighbor to the cache of the local node.
- * The new neighbor is put in the first null position.
- * @param neighbor The neighbor node to add
- * @return <tt>false</tt> if the neighbor is already present in the cache (this can happen when the peer requests a
- * new peer set to the tracker an there is still this neighbor within) or no place is available.
- * Otherwise, returns true if the node is correctly added to the cache.
- */
- public boolean addNeighbor(Node neighbor){
- if(search(neighbor.getID()) !=null){// if already exists
- // System.err.println("Node "+neighbor.getID() + " not added, already exist.");
- return false;
- }
- if(this.tracker == null){ // I'm in the tracker's BitTorrent protocol
- for(int i=0; i< nMaxNodes+maxGrowth; i++){
- if(cache[i].node == null){
- cache[i].node = neighbor;
- cache[i].status = 0; //chocked
- cache[i].interested = -1; //not interested
- this.nNodes++;
-
- //System.err.println("i: " + i +" nMaxNodes: " + nMaxNodes);
- return true;
- }
- }
- }
- else{
- if((nNodes+nBitfieldSent) < swarmSize){
- //System.out.println("I'm the node " + this.thisNodeID + ", trying to add node "+neighbor.getID());
- for(int i=0; i<swarmSize; i++){
- if(cache[i].node == null){
- cache[i].node = neighbor;
- cache[i].status = 0; //choked
- cache[i].interested = -1; // not interested
- byPeer[nNodes].peer = i;
- byPeer[nNodes].ID = neighbor.getID();
- sortByPeer();
- this.nNodes++;
- //System.out.println(neighbor.getID()+" added!");
- return true;
- }
- }
- System.out.println("Node not added, no places available");
- }
- }
- return false;
- }
-
- /**
- * Removes a neighbor from the cache of the local node.
- * @param neighbor The node to remove
- * @return true if the node is correctly removed, false otherwise.
- */
- public boolean removeNeighbor(Node neighbor) {
-
- if (neighbor == null)
- return true;
-
- // this is the tracker's bittorrent protocol
- if (this.tracker == null) {
- for (int i=0; i< (nMaxNodes+maxGrowth); i++) {
-
- // check the feasibility of the removal
- if ( (cache[i] != null) && (cache[i].node != null) &&
- (cache[i].node.getID() == neighbor.getID()) ) {
- cache[i].node = null;
- this.nNodes--;
- return true;
- }
- }
- return false;
- }
- // this is the bittorrent protocol of a peer
- else {
-
- Element e = search(neighbor.getID());
-
- if (e != null) {
- for (int i=0; i<nPieces; i++) {
- rarestPieceSet[i] -= swarm[e.peer][i];
- swarm[e.peer][i] = 0;
- }
-
- cache[e.peer].node = null;
- cache[e.peer].status = 0;
- cache[e.peer].interested = -1;
- unchokedBy[e.peer] = false;
- this.nNodes--;
- e.peer = -1;
- e.ID = Integer.MAX_VALUE;
- e.valueUP = 0;
- e.valueDOWN = 0;
- e.head20 = 0;
- e.head60 = 0;
- sortByPeer();
-
- return true;
- }
- }
- return false;
- }
-
- /**
- * Adds a request to the pendingRequest queue.
- * @param block The requested block
- * @return true if the request has been successfully added to the queue, false otherwise
- */
- private boolean addRequest(int block){
- int i=4;
- while(i>=0 && pendingRequest[i]!=-1){
- i--;
- }
- if(i>=0){
- pendingRequest[i] = block;
- return true;
- }
- else { // It should never happen
- //System.err.println("pendingRequest queue full");
- return false;
- }
- }
-
- /**
- * Removes the block with the given <tt>id</tt> from the {@link #pendingRequest} queue
- * and sorts the queue leaving the empty cell at the left.
- * @param id the id of the requested block
- */
- private void removeRequest(int id){
- int i = 4;
- for(; i>=0; i--){
- if(pendingRequest[i]==id)
- break;
- }
- for(; i>=0; i--){
- if(i==0)
- pendingRequest[i] = -1;
- else
- pendingRequest[i] = pendingRequest[i-1];
- }
- }
-
- /**
- * Requests new block until the {@link #pendingRequest} is full to the sender of the just received piece.
- * It calls {@link #getNewBlock(Node, int)} to implement the <i>strict priority</i> strategy.
- * @param node the local node
- * @param pid the BitTorrent protocol id
- * @param sender the sender of the just received received piece.
- */
- private void requestNextBlocks(Node node, int pid, int sender){
- int block = getNewBlock(node, pid);
- while(block != -2){
- if(unchokedBy[sender]==true && alive(cache[sender].node) && addRequest(block)){
- Object ev = new IntMsg(REQUEST, node, block,0);
-
-// long latency = ((Transport)node.getProtocol(tid)).getLatency(node,cache[sender].node);
-// EDSimulator.add(latency,ev,cache[sender].node,pid);
-
- ((Transport) node.getProtocol(tid)).send(node,cache[sender].node, ev, pid);
- cache[sender].justSent();
- }
- else{ // I cannot send request
- if(!alive(cache[sender].node) && cache[sender].node!=null){
- System.out.println("piece2 rm neigh "+ cache[sender].node.getID() );
- removeNeighbor(cache[sender].node);
- processNeighborListSize(node,pid);
- }
- return;
- }
- block = getNewBlock(node, pid);
- }
- }
-
- /**
- * It returns the id of the next block to request. Sends <tt>INTERESTED</tt> if the new
- * block belongs to a new piece.
- * It uses {@link #getBlock()} to get the next block of a piece and calls {@link #getPiece()}
- * when all the blocks for the {@link #currentPiece} have been requested.
- * @param node the local node
- * @param pid the BitTorrent protocol id
- * @return -2 if no more places available in the <tt>pendingRequest</tt> queue;<br/>
- * the value of the next block to request otherwise</p>
- */
- private int getNewBlock(Node node, int pid){
- int block = getBlock();
- if(block < 0){ // No more block to request for the current piece
-
- if(block ==-2) // Pending request queue full
- return -2;
-
- int newPiece = getPiece();
- if(newPiece == -1){ // no more piece to request
- return -2;
- }
-
- lastInterested = newPiece;
- Object ev = new IntMsg(INTERESTED, node, lastInterested,0);
-
- for(int j=0; j<swarmSize; j++){// send the interested message to those
- // nodes which have that piece
- if(alive(cache[j].node) && swarm[j][newPiece]==1){
-// long latency = ((Transport)node.getProtocol(tid)).getLatency(node,cache[j].node);
-// EDSimulator.add(latency,ev,cache[j].node,pid);
- ((Transport) node.getProtocol(tid)).send(node,cache[j].node, ev, pid);
- cache[j].justSent();
- }
- if(!alive(cache[j].node)){
- //System.out.println("piece1 rm neigh "+ cache[j].node.getID() );
-
- removeNeighbor(cache[j].node);
- processNeighborListSize(node,pid);
- }
- }
- block = getBlock();
- return block;
- }
- else{
- // block value referred to a real block
- return block;
- }
- }
-
- /**
- * Returns the next block to request for the {@link #currentPiece}.
- * @return an index of a block of the <tt>currentPiece</tt> if there are still
- * available places in the {@link #pendingRequest} queue;<br/>
- * -2 if the <tt>pendingRequest</tt> queue is full;<br/>
- * -1 if no more blocks to request for the current piece.
- */
- private int getBlock(){
- int i=4;
- while(i>=0 && pendingRequest[i]!=-1){ // i is the first empty position from the head
- i--;
- }
- if(i==-1){// No places in the pendingRequest available
- //System.out.println("Pendig request queue full!");
- return -2;
- }
- int j;
- //The queue is not empty & last requested block belongs to lastInterested piece
- if(i!=4 && decode(pendingRequest[i+1],0)==lastInterested)
- j=decode(pendingRequest[i+1],1)+1; // the block following the last requested
- else // I don't know which is the next block, so I search it.
- j=0;
- /* I search another block until the current has been already received.
- * If in pieceStatus at position j there is a block that belongs to
- * lastInterested piece, means that the block j has been already
- * received, otherwise I can request it.
- */
- while(j<16 && decode(pieceStatus[j],0)==lastInterested){
- j++;
- }
- if(j==16) // No more block to request for lastInterested piece
- return -1;
- return encode(lastInterested,j);
- }
-
- /**
- * Returns the next correct piece to download. It choose the piece by using the
- * <i>random first</i> and <i>rarest first</i> policy. For the beginning 4 pieces
- * of a file the first one is used then the pieces are chosen using <i>rarest first</i>.
- * @see "Documentation about the BitTorrent module"
- * @return the next piece to download. If the whole file has been requested
- * -1 is returned.
- */
- private int getPiece(){
- int piece = -1;
- if(nPieceCompleted < 4){ //Uses random first piece
- piece = CommonState.r.nextInt(nPieces);
- while(status[piece]==16 || piece == currentPiece) // until the piece is owned
- piece = CommonState.r.nextInt(nPieces);
- return piece;
- }
- else{ //Uses rarest piece first
- int j=0;
- for(; j<nPieces; j++){ // I find the first not owned piece
- if(status[j]==0){
- piece = j;
- if(piece != lastInterested) // teoretically it works because
- // there should be only one interested
- // piece not yet downloaded
- break;
- }
- }
- if(piece==-1){ // Never entered in the previous 'if' statement; for all
- // pieces an has been sent
- return -1;
- }
-
- int rarestPieces[] = new int[nPieces-j]; // the pieces with the less number of occurences\
- rarestPieces[0] = j;
- int nValues = 1; // number of pieces less distributed in the network
- for(int i=j+1; i<nPieces; i++){ // Finds the rarest piece not owned
- if(rarestPieceSet[i]< rarestPieceSet[rarestPieces[0]] && status[i]==0){ // if strictly less than the current one
- rarestPieces[0] = i;
- nValues = 1;
- }
- if(rarestPieceSet[i]==rarestPieceSet[rarestPieces[0]] && status[i]==0){ // if equal
- rarestPieces[nValues] = i;
- nValues++;
- }
- }
-
- piece = CommonState.r.nextInt(nValues); // one of the less owned pieces
- return rarestPieces[piece];
- }
- }
-
- /**
- * Returns the file's size as number of pieces of 256KB.
- * @return number of pieces that compose the file.
- */
- public int getNPieces(){
- return nPieces;
- }
- /**
- * Clone method of the class. Returns a deep copy of the BitTorrent class. Used
- * by the simulation to initialize the {@link peersim.core.Network}
- * @return the deep copy of the BitTorrent class.
- */
- public Object clone(){
- Object prot = null;
- try{
- prot = (BitTorrent)super.clone();
- }
- catch(CloneNotSupportedException e){};
-
- ((BitTorrent)prot).cache = new Neighbor[swarmSize];
- for(int i=0; i<swarmSize; i++){
- ((BitTorrent)prot).cache[i] = new Neighbor();
- }
-
- ((BitTorrent)prot).byPeer = new Element[swarmSize];
- for(int i=0; i<swarmSize; i++){
- ((BitTorrent)prot).byPeer[i] = new Element();
- }
-
- ((BitTorrent)prot).unchokedBy = new boolean[swarmSize];
-
- ((BitTorrent)prot).byBandwidth = new Element[swarmSize];
- ((BitTorrent)prot).status = new int[nPieces];
- ((BitTorrent)prot).pieceStatus = new int[16];
- for(int i=0; i<16;i++)
- ((BitTorrent)prot).pieceStatus[i] = -1;
- ((BitTorrent)prot).pendingRequest = new int[5];
- for(int i=0; i<5;i++)
- ((BitTorrent)prot).pendingRequest[i] = -1;
- ((BitTorrent)prot).rarestPieceSet = new int[nPieces];
- for(int i=0; i<nPieces;i++)
- ((BitTorrent)prot).rarestPieceSet[i] = 0;
- ((BitTorrent)prot).swarm = new int[swarmSize][nPieces];
- ((BitTorrent)prot).requestToServe = new Queue(20);
- ((BitTorrent)prot).incomingPieces = new Queue(100);
- return prot;
- }
-
- /**
- * Sorts {@link #byPeer} array by peer's ID. It implements the <i>InsertionSort</i>
- * algorithm.
- */
- public void sortByPeer(){
- int i;
-
- for(int j=1; j<swarmSize; j++) // out is dividing line
- {
- Element key = new Element();
- byPeer[j].copyTo(key) ; // remove marked item
- i = j-1; // start shifts at out
- while(i>=0 && (byPeer[i].ID > key.ID)) // until one is smaller,
- {
- byPeer[i].copyTo(byPeer[i+1]); // shift item right,
- i--; // go left one position
- }
- key.copyTo(byPeer[i+1]); // insert marked item
- }
-
- }
-
- /**
- * Sorts the array {@link #byBandwidth} using <i>QuickSort</i> algorithm.
- * <tt>null</tt> elements and seeders are moved to the end of the array.
- */
- public void sortByBandwidth() {
- quicksort(0, swarmSize-1);
- }
-
- /**
- * Used by {@link #sortByBandwidth()}. It's the implementation of the
- * <i>QuickSort</i> algorithm.
- * @param left the leftmost index of the array to sort.
- * @param right the rightmost index of the array to sort.
- */
- private void quicksort(int left, int right) {
- if (right <= left) return;
- int i = partition(left, right);
- quicksort(left, i-1);
- quicksort(i+1, right);
- }
-
- /**
- * Used by {@link #quicksort(int, int)}, partitions the subarray to sort returning
- * the splitting point as stated by the <i>QuickSort</i> algorithm.
- * @see "The <i>QuickSort</i> algorithm".
- */
- private int partition(int left, int right) {
- int i = left - 1;
- int j = right;
- while (true) {
- while (greater(byBandwidth[++i], byBandwidth[right])) // find item on left to swap
- ; // a[right] acts as sentinel
- while (greater(byBandwidth[right], byBandwidth[--j])) { // find item on right to swap
- if (j == left) break; // don't go out-of-bounds
- }
- if (i >= j) break; // check if pointers cross
- swap(i, j); // swap two elements into place
- }
- swap(i, right); // swap with partition element
- return i;
- }
-
- /**
- * Aswers to the question "is x > y?". Compares the {@link Element}s given as
- * parameters. <tt>Element x</tt> is greater than <tt>y</tt> if isn't <tt>null</tt>
- * and in the last 20 seconds the local node has downloaded ("uploaded" if the local node is a
- * seeder) more blocks than from <tt>y</tt>.
- * @param x the first <tt>Element</tt> to compare.
- * @param y the second <tt>Element</tt> to compare
- * @return <tt>true</tt> if x > y;<br/>
- * <tt>false</tt> otherwise.
- */
- private boolean greater(Element x, Element y) {
- /*
- * Null elements and seeders are shifted at the end
- * of the array
- */
- if (x==null) return false;
- if (y==null) return true;
- if (x.isSeeder) return false;
- if (y.isSeeder) return true;
-
- // if the local node is a leecher
- if (peerStatus==0) {
- if ((x.valueDOWN - x.head20) >
- (y.valueDOWN -y.head20))
- return true;
- else return false;
- }
-
- // if peerStatus==1 (the local node is a seeder)
- else {
- if ((x.valueUP - x.head20) >
- (y.valueUP -y.head20))
- return true;
- else return false;
- }
- }
-
- /**
- * Swaps {@link Element} <tt>i</tt> with <tt>j</tt> in the {@link #byBandwidth}.<br/>
- * Used by {@link #partition(int, int)}
- * @param i index of the first element to swap
- * @param j index of the second element to swap
- */
- private void swap(int i, int j) {
- Element swap = byBandwidth[i];
- byBandwidth[i] = byBandwidth[j];
- byBandwidth[j] = swap;
- }
-
- /** Searches the node with the given ID. It does a dychotomic
- * search.
- * @param ID ID of the node to search.
- * @return the {@link Element} in {@link #byPeer} which represents the node with the
- * given ID.
- */
- public Element search(long ID){
- int low = 0;
- int high = swarmSize-1;
- int p = low+((high-low)/2); //Initial probe position
- while ( low <= high) {
- if ( byPeer[p] == null || byPeer[p].ID > ID)
- high = p - 1;
- else {
- if( byPeer[p].ID < ID ) //Wasteful second comparison forced by syntax limitations.
- low = p + 1;
- else
- return byPeer[p];
- }
- p = low+((high-low)/2); //Next probe position.
- }
- return null;
- }
-}
-
-/**
- * This class is used to store the main informations about a neighbors regarding
- * the calculation of the Downloading/Uploading rates. Is the class of items in
- * {@link example.bittorrent.BitTorrent#byPeer} and {@link example.bittorrent.BitTorrent#byBandwidth}.
- */
-class Element{
- /**
- * ID of the represented node.
- */
- public long ID = Integer.MAX_VALUE;
- /**
- * Index position of the node in the {@link example.bittorrent.BitTorrent#cache} array.
- */
- public int peer = -1;
- /**
- * Number of blocks uploaded to anyone since the beginning.
- */
- public int valueUP = 0;
- /**
- * Number of blocks downloaded from anyone since the beginning.
- */
- public int valueDOWN = 0;
- /**
- * Value of either {@link #valueUP} or {@link #valueDOWN} (depending by
- * {@link example.bittorrent.BitTorrent#peerStatus}) 20 seconds before.
- */
- public int head20 = 0;
- /**
- * Value of either {@link #valueUP} or {@link #valueDOWN} (depending by
- * {@link example.bittorrent.BitTorrent#peerStatus}) 60 seconds before.
- */
- public int head60 = 0;
- /**
- * <tt>true</tt> if the node is a seeder, <tt>false</tt> otherwise.
- */
- public boolean isSeeder = false;
- /**
- * Makes a deep copy of the Element to <tt>destination</tt>
- * @param destination Element instance where to make the copy
- */
- public void copyTo(Element destination){
- destination.ID = this.ID;
- destination.peer = this.peer;
- destination.valueUP = this.valueUP;
- destination.valueDOWN = this.valueDOWN;
- destination.head20 = this.head20;
- destination.head60 = this.head60;
- }
-}
-
-/**
- * This class stores information about the neighbors regarding their status. It is
- * the type of the items in the {@link example.bittorrent.BitTorrent#cache}.
- */
-class Neighbor{
- /**
- * Reference to the node in the {@link peersim.core.Network}.
- */
- public Node node = null;
- /**
- * -1 means not interested<br/>
- * Other values means the last piece number for which the node is interested.
- */
- public int interested;
- /**
- * 0 means CHOKED<br/>
- * 1 means UNCHOKED<br/>
- * 2 means SNUBBED_BY. If this value is set and the node is to be unchocked,
- * value 2 has the priority.
- */
- public int status;
- /**
- * Last time a message from the node represented has been received.
- */
- public long lastSeen = 0;
- /**
- * Last time a message to the node represented has been sent.
- */
- public long lastSent = 0;
-
- /**
- * Sets the last time the neighbor was seen.
- */
- public void isAlive(){
- long now = CommonState.getTime();
- this.lastSeen = now;
- }
-
- /*
- * Sets the last time the local peer sent something to the neighbor.
- */
- public void justSent(){
- long now = CommonState.getTime();
- this.lastSent = now;
- }
-
-}
-
-/**
- * Class type of the queues's items in {@link example.bittorrent.BitTorrent#incomingPieces}
- * and {@link example.bittorrent.BitTorrent#requestToServe}.
- */
-class Queue{
- int maxSize;
- int head = 0;
- int tail = 0;
- int dim = 0;
- Request queue[];
-
- /**
- * Public constructor. Creates a queue of size <tt>size</tt>.
- */
- public Queue(int size){
- maxSize = size;
- queue = new Request[size];
- for(int i=0; i< size; i++)
- queue[i]= new Request();
- }
-
- /**
- * Enqueues the request of the block <tt>id</tt> and its <tt>sender</tt>
- * @param id the id of the block in the request
- * @param sender a reference to the sender of the request
- * @return <tt>true</tt> if the request has been correctly added, <tt>false</tt>
- * otherwise.
- */
- public boolean enqueue(int id, Node sender){
- if(dim < maxSize){
- queue[tail%maxSize].id = id;
- queue[tail%maxSize].sender = sender;
- tail++;
- dim++;
- return true;
- }
- else return false;
- }
-
- /**
- * Returns the {@link Request} in the head of the queue.
- * @return the element in the head.<br/>
- * <tt>null</tt> if the queue is empty.
- */
- public Request dequeue(){
- Request value;
- if(dim > 0){
- value = queue[head%maxSize];
- head++;
- dim--;
- return value;
- }
- else return null; //empty queue
- }
-
- /**
- * Returns the status of the queue.
- * @return <tt>true</tt> if the queue is empty, <tt>false</tt>
- * otherwise.
- */
- public boolean empty(){
- return (dim == 0);
- }
-
- /**
- * Returns <tt>true</tt> if block given as parameter is in.
- * @param value the id of the block to search.
- * @return <tt>true</tt> if the block <tt>value</tt> is in the queue, <tt>false</tt>
- * otherwise.
- */
- public boolean contains(int value){
- if(empty())
- return false;
- for(int i=head; i<head+dim; i++){
- if(queue[i%maxSize].id == value)
- return true;
- }
- return false;
- }
-
- /**
- * Removes a request from the queue.
- * @param sender the sender of the request.
- * @param value the id of the block requested.
- * @return <tt>true</tt> if the request has been correctly removed, <tt>false</tt>
- * otherwise.
- */
- public boolean remove(Node sender, int value){
- if(empty())
- return false;
- for(int i=head; i<head+dim; i++){
- if(queue[i%maxSize].id == value && queue[i%maxSize].sender == sender){
- for(int j=i; j>head; j--){ // Shifts the elements for the removal
- queue[j%maxSize]= queue[(j-1)%maxSize];
- }
- head++;
- dim--;
- return true;
- }
- }
- return false;
- }
-}
-
-/**
- * This class represent an enqueued request of a block.
- */
-class Request{
- /**
- * The id of the block.
- */
- public int id;
- /**
- * The sender of the request.
- */
- public Node sender;
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2007-2008 Fabrizio Frioli, Michele Pedrolli
- *
- * 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.
- *
- * --
- *
- * Please send your questions/suggestions to:
- * {fabrizio.frioli, michele.pedrolli} at studenti dot unitn dot it
- *
- */
-
-package example.bittorrent;
-
-import peersim.core.*;
-
-/**
- * This class is a {@link SimpleMsg} and represents the <tt>bitfield</tt>
- * message.
- */
-public class BitfieldMsg extends SimpleMsg{
- /**
- * The status of the file to transmit to neighbors nodes
- */
- int[] array;
-
- /**
- * Defines the type of the Bitfield message. If <tt>isRequest</tt> is true, then
- * the message is a request of subscription; otherwise the message is a response.
- */
- boolean isRequest;
-
- /**
- * <p>The ACK value used to implement <i>ack</i> and <i>nack</i> messages.</p>
- * <p>It has value <tt>true</tt> if the message is a reponse and the sender has inserted
- * the receiver in its own cache of neighbors.<br/>
- * If for some reason (for instance the cache had already 80 peer inside at the moment of the
- * request) it was not possible to insert the peer, the value is <tt>false</tt>.<br/>
- * It has value <tt>false</tt> also if the message is a request and is sent when occours
- * an unespected message.
- * </p>
- * @see "The documentation to understand the 4 different types of Bitfield messages"
- */
- boolean ack;
-
- /**
- * The basic constructor of the Bitfield message.
- * @param type The type of the message, according to {@link SimpleMsg}
- * @param isRequest Defines if the message is a request or not
- * @param ack Defines if the message type is an <i>ack</i> or a <i>nack</i>
- * @param sender The sender node
- * @param source The array containing the status of the file
- * @param size The size of the array
- */
- public BitfieldMsg(int type, boolean isRequest, boolean ack, Node sender, int source[], int size){
- super.type = type;
- super.sender = sender;
- this.isRequest = isRequest;
- this.ack = ack;
- this.array = new int[size];
- for(int i=0; i<size;i++){ // it sends a copy
- if(source[i]==16)
- this.array[i] = 1;
- else
- this.array[i] = 0;
- }
- }
-
- /**
- * Gets the array containing the status of the file.
- * @return The status of the file
- */
- public int[] getArray(){
- return this.array;
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2007-2008 Fabrizio Frioli, Michele Pedrolli
- *
- * 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.
- *
- * --
- *
- * Please send your questions/suggestions to:
- * {fabrizio.frioli, michele.pedrolli} at studenti dot unitn dot it
- *
- */
-
-package example.bittorrent;
-
-import peersim.core.*;
-import psgsim.Sizable;
-
-/**
- * This class is a {@link SimpleMsg} and acts as a container for a message that
- * uses only an integer value.
- */
-public class IntMsg extends SimpleMsg implements Sizable {
-
- /**
- * The data value (an integer) contained in the message.
- */
- private int integer;
- private double size;
-
- /**
- * The basic constructor of the message.
- *
- * @param type
- * the type of the message
- * @param sender
- * The sender node
- * @param value
- * The data value of the message
- */
- public IntMsg(int type, Node sender, int value, double size) {
- super.type = type;
- super.sender = sender;
- this.integer = value;
- this.size = size;
- }
-
- /**
- * Gets the value contained in the message.
- *
- * @return the integer value contained in the message
- */
- public int getInt() {
- return this.integer;
- }
-
- @Override
- public double getSize() {
- // TODO Auto-generated method stub
- return size;
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2007-2008 Fabrizio Frioli, Michele Pedrolli
- *
- * 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.
- *
- * --
- *
- * Please send your questions/suggestions to:
- * {fabrizio.frioli, michele.pedrolli} at studenti dot unitn dot it
- *
- */
-
-package example.bittorrent;
-
-import peersim.config.*;
-import peersim.core.*;
-import peersim.transport.*;
-import peersim.edsim.*;
-
-/**
- * This {@link Control} can change the size of networks by adding and removing
- * nodes. This class supports only permanent removal of nodes and the addition
- * of brand new nodes. That is, temporary downtime is not supported by this
- * class.
- */
-public class NetworkDynamics implements Control {
- private static final int TRACKER = 11;
- private static final int CHOKE_TIME = 13;
- private static final int OPTUNCHK_TIME = 14;
- private static final int ANTISNUB_TIME = 15;
- private static final int CHECKALIVE_TIME = 16;
- private static final int TRACKERALIVE_TIME = 17;
-
- /**
- * The protocol to operate on.
- *
- * @config
- */
- private static final String PAR_PROT = "protocol";
-
- /**
- * Nodes are removed until the size specified by this parameter is reached.
- * The network will never go below this size as a result of this class.
- * Defaults to 0.
- *
- * @config
- */
- private static final String PAR_MIN = "minsize";
-
- /**
- * Specifies if the tracker can disappear from the network. 0 means no, 1
- * means yes
- *
- * @config
- */
- private static final String PAR_TRACKER_DIE = "tracker_can_die";
-
- /**
- * The Transport used by the the control.
- *
- * @config
- */
- private static final String PAR_TRANSPORT = "transport";
-
- /**
- * Specifies how many nodes will be added to the network.
- *
- * @config
- */
- private static final String PAR_ADD = "add";
-
- /**
- * Specifies how many nodes will be removed from the network.
- *
- * @config
- */
- private static final String PAR_REMOVE = "remove";
-
- /*
- * The following are local variables, obtained from config property.
- */
- private final int pid;
- private final int tid;
- private final int maxSize;
- private final int minsize;
- private boolean trackerCanDie = false; // false (value 0) by default
- private final int add; // number of nodes to be added
- private final int remove; // number of nodes to be removed
-
- private final NodeInitializer init;
- private Node tracker;
-
- /**
- * Standard constructor that reads the configuration parameters. Invoked by
- * the simulation engine.
- *
- * @param prefix
- * the configuration prefix for this class
- */
- public NetworkDynamics(String prefix) {
- pid = Configuration.getPid(prefix + "." + PAR_PROT);
- minsize = Configuration.getInt(prefix + "." + PAR_MIN, 0);
- tid = Configuration.getPid(prefix + "." + PAR_TRANSPORT);
- add = Configuration.getInt(prefix + "." + PAR_ADD);
- remove = Configuration.getInt(prefix + "." + PAR_REMOVE);
-
- /*
- * By default, the tracker can not disappear. If
- * control.dynamics.tracker_can_die is set to 1, the tracker can die.
- */
- if (Configuration.getInt(prefix + "." + PAR_TRACKER_DIE) == 1) {
- trackerCanDie = true;
- }
-
- init = new NodeInitializer("init.net");
- tracker = Network.get(0);
-
- maxSize = (Network.size() - 1)
- + ((BitTorrent) tracker.getProtocol(pid)).maxGrowth;
- }
-
- /**
- * Adds n nodes to the network. New nodes can be added only if the tracker
- * is up.
- *
- * @param n
- * the number of nodes to add, must be non-negative.
- */
- protected void add(int n) {
- if (n == 0)
- return;
- // tracker is up
- if (tracker.isUp()) {
- for (int i = 0; i < n; ++i) {
- // create a new node
- Node nodeToBeAdded = (Node) Network.prototype.clone();
-
- // add the new node to the network
- Network.add(nodeToBeAdded); // questo nodo sara' in posizione
- // Network.len -1
-
- /*
- * Initialize the new node using the NodeInitializer class; this
- * it the same as
- * init.initialize(Network.get(Network.size()-1));
- */
- init.initialize(nodeToBeAdded);
-
- /*
- * The new node sends a TRACKER message to the tracker, asking
- * for a list of peers. The tracker will respond with a PEERSET
- * message. All the related events are also attached to the new
- * node.
- */
- long latency =((Transport)nodeToBeAdded.getProtocol(tid)).getLatency(nodeToBeAdded,tracker);
- Object ev = new SimpleMsg(TRACKER, nodeToBeAdded);
- EDSimulator.add(latency,ev,tracker,pid);
-// ((Transport) nodeToBeAdded.getProtocol(tid)).send(
-// nodeToBeAdded, tracker, ev, pid);
-
- ev = new SimpleEvent(CHOKE_TIME);
- EDSimulator.add(10000, ev, nodeToBeAdded, pid);
- ev = new SimpleEvent(OPTUNCHK_TIME);
- EDSimulator.add(30000, ev, nodeToBeAdded, pid);
- ev = new SimpleEvent(ANTISNUB_TIME);
- EDSimulator.add(60000, ev, nodeToBeAdded, pid);
- ev = new SimpleEvent(CHECKALIVE_TIME);
- EDSimulator.add(120000, ev, nodeToBeAdded, pid);
- ev = new SimpleEvent(TRACKERALIVE_TIME);
- EDSimulator.add(1800000, ev, nodeToBeAdded, pid);
-
- // add the new node to the tracker's cache
- if (((BitTorrent) tracker.getProtocol(pid))
- .addNeighbor(nodeToBeAdded))
- System.out
- .println("DYN: A new node has been added to the network.");
- }
- }
- /*
- * Otherwise, the tracker is down and no new nodes can be added to the
- * network.
- */
- else
- System.out.println("DYN: Tracker is down. No new nodes added.");
- }
-
- /**
- * Removes n nodes from the network. A node can be removed either if the
- * tracker is up or down; if the tracker is up, the node to be removed will
- * be removed also from the tracker's cache.
- *
- * @param n
- * the number of nodes to remove.
- */
- protected void remove(int n) {
- // the index of the node to be removed
- int nodeIndex = 0;
-
- for (int i = 0; i < n; ++i) {
- nodeIndex = CommonState.r.nextInt(Network.size());
- // if the tracker can not disappear from the network
- if (!trackerCanDie) {
- /*
- * Choose an index for the node to be removed. The value 0 will
- * be discarded, since the tracker cannot disappear. Non
- * existing nodes cannot be removed: if the returned index
- * corresponds to a non-existing node, a new index will be
- * generated.
- */
- while (nodeIndex == 0) {
- nodeIndex = CommonState.r.nextInt(Network.size());
- }
- }
- // otherwise, also the tracker can disappear
- else {
- nodeIndex = CommonState.r.nextInt(Network.size());
- }
-
- // a warning message
- // if (nodeIndex==0)
- // System.out.println("DYN: The tracker is going to disapper.");
-
- // remove the node with the given index from the network
- Node nodeToBeRemoved = Network.remove(nodeIndex);
-
- // then remove it from the tracker's cache, if it is possible (= the
- // tracker is up);
- if (tracker.isUp()) {
- if (((BitTorrent) tracker.getProtocol(pid))
- .removeNeighbor(nodeToBeRemoved))
- System.err
- .println("DYN: A node has been removed from the network.");
- } else { // the tracker is down
- System.err.println("DYN: The tracker is DOWN!");
- }
- }
- }
-
- /**
- * Calls {@link #add(int)} or {@link #remove} with the parameters defined by
- * the configuration.
- *
- * @return always false
- */
- public boolean execute() {
- int choice = (CommonState.r.nextInt(2)); // 0 or 1
- // adding new nodes
- if (choice == 0) {
- /*
- * If the specified number of nodes cannot be added, it tries to add
- * a less number of nodes without going out of bounds. Otherwise,
- * all specified nodes will be added.
- */
- if (Network.size() + this.add > maxSize) {
- System.err.println("DYN: " + (maxSize - Network.size())
- + " nodes will be added.");
- add(maxSize - Network.size());
- } else {
- System.err
- .println("DYN: " + this.add + " nodes will be added.");
- add(this.add);
- }
- }
- // removing existing nodes
- else {
- if (Network.size() - this.remove < minsize) {
- System.err.println("DYN: " + (Network.size() - minsize)
- + " nodes will be removed.");
- remove(Network.size() - minsize);
- } else {
- System.err.println("DYN: " + this.remove
- + " nodes will be removed.");
- remove(this.remove);
- }
- }
- return false;
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2007-2008 Fabrizio Frioli, Michele Pedrolli
- *
- * 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.
- *
- * --
- *
- * Please send your questions/suggestions to:
- * {fabrizio.frioli, michele.pedrolli} at studenti dot unitn dot it
- *
- */
-
-package example.bittorrent;
-
-import peersim.core.*;
-import peersim.config.Configuration;
-import peersim.edsim.EDSimulator;
-import peersim.transport.Transport;
-import java.util.Random;
-
-/**
- * This {@link Control} ...
- */
-public class NetworkInitializer implements Control {
- /**
- * The protocol to operate on.
- *
- * @config
- */
- private static final String PAR_PROT="protocol";
-
- private static final String PAR_TRANSPORT="transport";
-
- private static final int TRACKER = 11;
-
- private static final int CHOKE_TIME = 13;
-
- private static final int OPTUNCHK_TIME = 14;
-
- private static final int ANTISNUB_TIME = 15;
-
- private static final int CHECKALIVE_TIME = 16;
-
- private static final int TRACKERALIVE_TIME = 17;
-
- /** Protocol identifier, obtained from config property */
- private final int pid;
- private final int tid;
- private NodeInitializer init;
-
- private Random rnd;
-
- public NetworkInitializer(String prefix) {
- pid = Configuration.getPid(prefix+"."+PAR_PROT);
- tid = Configuration.getPid(prefix+"."+PAR_TRANSPORT);
- init = new NodeInitializer(prefix);
- }
-
- public boolean execute() {
- int completed;
- Node tracker = Network.get(0);
-
- // manca l'inizializzazione del tracker;
-
- ((BitTorrent)Network.get(0).getProtocol(pid)).initializeTracker();
-
- for(int i=1; i<Network.size(); i++){
- System.err.println("chiamate ad addNeighbor " + i);
- ((BitTorrent)Network.get(0).getProtocol(pid)).addNeighbor(Network.get(i));
- init.initialize(Network.get(i));
- }
- for(int i=1; i< Network.size(); i++){
- Node n = Network.get(i);
-
- Object ev = new SimpleMsg(TRACKER, n);
- long latency = ((Transport)n.getProtocol(tid)).getLatency(n,tracker);
- EDSimulator.add(latency,ev,tracker,pid);
-// ((Transport) n.getProtocol(tid)).send(n,tracker, ev, pid);
-
- ev = new SimpleEvent(CHOKE_TIME);
- EDSimulator.add(10000,ev,n,pid);
- ev = new SimpleEvent(OPTUNCHK_TIME);
- EDSimulator.add(30000,ev,n,pid);
- ev = new SimpleEvent(ANTISNUB_TIME);
- EDSimulator.add(60000,ev,n,pid);
- ev = new SimpleEvent(CHECKALIVE_TIME);
- EDSimulator.add(120000,ev,n,pid);
- ev = new SimpleEvent(TRACKERALIVE_TIME);
- EDSimulator.add(1800000,ev,n,pid);
- }
- return true;
- }
-
- }
+++ /dev/null
-/*
- * Copyright (c) 2007-2008 Fabrizio Frioli, Michele Pedrolli
- *
- * 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.
- *
- * --
- *
- * Please send your questions/suggestions to:
- * {fabrizio.frioli, michele.pedrolli} at studenti dot unitn dot it
- *
- */
-
-package example.bittorrent;
-
-import peersim.core.*;
-import peersim.config.Configuration;
-
-/**
- * This class provides a way to initialize a single node of the network.
- * The initialization is performed by choosing the bandwidth of the node
- * and choosing how much the shared file has been downloaded.
- */
-public class NodeInitializer{
-
- /**
- * The protocol to operate on.
- * @config
- */
- private static final String PAR_PROT="protocol";
-
- /**
- * The percentage of nodes with no downloaded pieces.
- * @config
- * @see "The documentation for an example on how to properly set this parameter."
- */
- private static final String PAR_NEWER_DISTR="newer_distr";
-
- /**
- * The percentage of seeders in the network.
- * @config
- */
- private static final String PAR_SEEDER_DISTR="seeder_distr";
-
- /**
- * The percentage of nodes with no downloaded pieces,
- * as defined in {@see #PAR_NEWER_DISTR}.
- */
- private int newerDistr;
-
- /**
- * The percentage of seeder nodes,
- * as defined in {@see #PAR_SEEDER_DISTR}.
- */
- private int seederDistr;
-
- /**
- * The BitTorrent protocol ID.
- */
- private final int pid;
-
- /**
- * The basic constructor of the class, which reads the parameters
- * from the configuration file.
- * @param prefix the configuration prefix for this class
- */
- public NodeInitializer(String prefix){
- pid = Configuration.getPid(prefix+"."+PAR_PROT);
- newerDistr = Configuration.getInt(prefix+"."+PAR_NEWER_DISTR);
- seederDistr = Configuration.getInt(prefix+"."+PAR_SEEDER_DISTR);
- }
-
- /**
- * Initializes the node <tt>n</tt> associating it
- * with the BitTorrent protocol and setting the reference to the tracker,
- * the status of the file and the bandwidth.
- * @param n The node to initialize
- */
- public void initialize(Node n){
- Node tracker = Network.get(0);
- BitTorrent p;
- p = (BitTorrent)n.getProtocol(pid);
- p.setTracker(tracker);
- p.setThisNodeID(n.getID());
- setFileStatus(p);
- setBandwidth(p);
- }
-
- /**
- * Sets the status of the shared file according to the
- * probability value given by {@link #getProbability()}.
- * @param p The BitTorrent protocol
- */
- private void setFileStatus(BitTorrent p){
- int percentage = getProbability();
- choosePieces(percentage, p);
- }
-
- /**
- * Set the maximum bandwidth for the node, choosing
- * uniformly at random among 4 values.
- * <p>
- * The allowed bandwidth speed are 640 Kbps, 1 Mbps, 2 Mbps and 4 Mbps.
- * </p>
- * @param p The BitTorrent protocol
- */
- private void setBandwidth(BitTorrent p){
- int value = CommonState.r.nextInt(4);
- switch(value){
- case 0: p.setBandwidth(640);break; //640Kbps
- case 1: p.setBandwidth(1024);break;// 1Mbps
- case 2: p.setBandwidth(2048);break;// 2Mbps
- case 3: p.setBandwidth(4096);break; //4Mbps
- }
- }
-
- /**
- * Sets the completed pieces for the given protocol <tt>p</tt>.
- * @parm percentage The percentage of the downloaded pieces, according to {@link #getProbability()}
- * @param p the BitTorrent protocol
- */
- private void choosePieces(int percentage, BitTorrent p){
- double temp = ((double)p.nPieces/100.0)*percentage; // We use a double to avoid the loss of precision
- // during the division operation
- int completed = (int)temp; //integer number of piece to set as completed
- //0 if the peer is a newer
- p.setCompleted(completed);
- if(percentage == 100)
- p.setPeerStatus(1);
- int tmp;
- while(completed!=0){
- tmp = CommonState.r.nextInt(p.nPieces);
- if(p.getStatus(tmp)!=16){
- p.setStatus(tmp, 16);
- completed--;
- }
- }
- }
-
- /**
- * Gets a probability according with the parameter <tt>newer_distr</tt>
- * defined in the configuration file.
- * @return the probabilty value, where 0 means that the peer is new and no pieces has been downloaded,
- * 100 means that the peer is a seeder; other values defines a random probability.
- * @see #PAR_NEWER_DISTR
- */
- private int getProbability(){
- int value = CommonState.r.nextInt(100);
- if((value+1)<=seederDistr)
- return 100;
- value = CommonState.r.nextInt(100);
- if((value+1)<=newerDistr){
- return 0; // A newer peer, with probability newer_distr
- }
- else{
- value = CommonState.r.nextInt(9);
- return (value+1)*10;
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2007-2008 Fabrizio Frioli, Michele Pedrolli
- *
- * 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.
- *
- * --
- *
- * Please send your questions/suggestions to:
- * {fabrizio.frioli, michele.pedrolli} at studenti dot unitn dot it
- *
- */
-package example.bittorrent;
-
-import peersim.core.*;
-
-/**
- * This class is a {@link SimpleMsg} and represents the <tt>peerset</tt>
- * message used by the tracker to send to the peers a list of neighbors.
- */
-public class PeerSetMsg extends SimpleMsg{
-
- /**
- * The set of "friends" peers sent by the tracker to each node.
- */
- private Neighbor[] peerSet;
-
- /**
- * Initializes a new <tt>peerset</tt> message.
- * @param type is the type of the message (it should be 12)
- * @param array is the array containing the references to the neighbor nodes
- * @param sender the sender node
- * @see SimpleEvent
- */
- public PeerSetMsg(int type, Neighbor []array, Node sender){
- super.type = type;
- peerSet = array; // references to the effective nodes
- super.sender = sender;
- }
-
- /**
- * Gets the peer set.
- * @return the peer set, namely the set of neighbor nodes.
- */
- public Neighbor[] getPeerSet(){
- return this.peerSet;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007-2008 Fabrizio Frioli, Michele Pedrolli
- *
- * 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.
- *
- * --
- *
- * Please send your questions/suggestions to:
- * {fabrizio.frioli, michele.pedrolli} at studenti dot unitn dot it
- *
- */
-
-package example.bittorrent;
-
-/**
- * This class defines a simple event. A simple event is characterized only
- * by its type.
- */
-public class SimpleEvent {
-
- /**
- * The identifier of the type of the event.
- * <p>
- * The available identifiers for event type are:<br/>
- * <ul>
- * <li>1 is KEEP_ALIVE message</li>
- * <li>2 is CHOKE message</li>
- * <li>3 is UNCHOKE message</li>
- * <li>4 is INTERESTED message</li>
- * <li>5 is NOT_INTERESTED message</li>
- * <li>6 is HAVE message</li>
- * <li>7 is BITFIELD message</li>
- * <li>8 is REQUEST message</li>
- * <li>9 is PIECE message</li>
- * <li>10 is CANCEL message</li>
- * <li>11 is TRACKER message</li>
- * <li>12 is PEERSET message</li>
- * <li>13 is CHOKE_TIME event</li>
- * <li>14 is OPTUNCHK_TIME event</li>
- * <li>15 is ANTISNUB_TIME event</li>
- * <li>16 is CHECKALIVE_TIME event</li>
- * <li>17 is TRACKERALIVE_TIME event</li>
- * <li>18 is DOWNLOAD_COMPLETED event</li>
- *</ul></p>
- */
- protected int type;
-
- public SimpleEvent(){
- }
-
- /**
- * Initializes the type of the event.
- * @param type The identifier of the type of the event
- */
- public SimpleEvent(int type){
- this.type = type;
- }
-
- /**
- * Gets the type of the event.
- * @return The type of the current event.
- */
- public int getType(){
- return this.type;
- }
-}
-
-
+++ /dev/null
-/*
- * Copyright (c) 2007-2008 Fabrizio Frioli, Michele Pedrolli
- *
- * 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.
- *
- * --
- *
- * Please send your questions/suggestions to:
- * {fabrizio.frioli, michele.pedrolli} at studenti dot unitn dot it
- *
- */
-
-package example.bittorrent;
-
-import peersim.core.*;
-
-/**
- * This class defines a simple message.
- * A simple message has its type and the reference of the sender node.
- * @see SimpleEvent
- */
-public class SimpleMsg extends SimpleEvent {
-
- /**
- * The sender of the message.
- */
- protected Node sender;
-
- public SimpleMsg(){
- }
-
- /**
- * Initializes the simple message with its type and sender.
- * @param type The identifier of the type of the message
- * @param sender The sender of the message
- */
- public SimpleMsg(int type, Node sender){
- super.type = type;
- this.sender = sender;
- }
-
- /**
- * Gets the sender of the message.
- * @return The sender of the message.
- */
- public Node getSender(){
- return this.sender;
- }
-}
+++ /dev/null
-package example.chord;\r
-\r
-import java.math.BigInteger;\r
-import java.util.Random;\r
-import peersim.config.Configuration;\r
-import peersim.core.CommonState;\r
-import peersim.core.Network;\r
-import peersim.core.Node;\r
-import peersim.dynamics.NodeInitializer;\r
-\r
-public class ChordInitializer implements NodeInitializer {\r
-\r
- private static final String PAR_PROT = "protocol";\r
-\r
- private int pid = 0;\r
-\r
- private ChordProtocol cp;\r
-\r
- public ChordInitializer(String prefix) {\r
- pid = Configuration.getPid(prefix + "." + PAR_PROT);\r
- }\r
-\r
- public void initialize(Node n) {\r
- cp = (ChordProtocol) n.getProtocol(pid);\r
- join(n);\r
- }\r
-\r
- public void join(Node myNode) {\r
- Random generator = new Random();\r
- //Random generator = new Random(1234567890);\r
- cp.predecessor = null;\r
- // search a node to join\r
- Node n;\r
- do {\r
- n = Network.get(generator.nextInt(Network.size()));\r
- } while (n == null || n.isUp() == false);\r
- cp.m = ((ChordProtocol) n.getProtocol(pid)).m;\r
- cp.chordId = new BigInteger(cp.m, CommonState.r);\r
- ChordProtocol cpRemote = (ChordProtocol) n.getProtocol(pid);\r
-\r
- Node successor = cpRemote.find_successor(cp.chordId);\r
- cp.fails = 0;\r
- cp.stabilizations = 0;\r
- cp.varSuccList = cpRemote.varSuccList;\r
- cp.varSuccList = 0;\r
- cp.succLSize = cpRemote.succLSize;\r
- cp.successorList = new Node[cp.succLSize];\r
- cp.successorList[0] = successor;\r
- cp.fingerTable = new Node[cp.m];\r
- long succId = 0;\r
- BigInteger lastId = ((ChordProtocol) Network.get(Network.size() - 1)\r
- .getProtocol(pid)).chordId;\r
- do {\r
- cp.stabilizations++;\r
- succId = cp.successorList[0].getID();\r
- cp.stabilize(myNode);\r
- if (((ChordProtocol) cp.successorList[0].getProtocol(pid)).chordId\r
- .compareTo(cp.chordId) < 0) {\r
- cp.successorList[0] = ((ChordProtocol) cp.successorList[0]\r
- .getProtocol(pid)).find_successor(cp.chordId);\r
- }\r
- // controllo di non essere l'ultimo elemento della rete\r
- if (cp.chordId.compareTo(lastId) > 0) {\r
- cp.successorList[0] = Network.get(0);\r
- break;\r
- }\r
- } while (cp.successorList[0].getID() != succId\r
- || ((ChordProtocol) cp.successorList[0].getProtocol(pid)).chordId\r
- .compareTo(cp.chordId) < 0);\r
- cp.fixFingers();\r
- }\r
-}\r
+++ /dev/null
-/**\r
- * \r
- */\r
-package example.chord;\r
-\r
-/**\r
- * @author Andrea\r
- * \r
- */\r
-public interface ChordMessage {\r
-\r
-}\r
+++ /dev/null
-/**\r
- * \r
- */\r
-package example.chord;\r
-\r
-import peersim.config.Configuration;\r
-import peersim.core.CommonState;\r
-import peersim.core.Network;\r
-import peersim.core.Node;\r
-import peersim.edsim.EDProtocol;\r
-import peersim.transport.Transport;\r
-\r
-import java.math.*;\r
-\r
-import org.simgrid.msg.Host;\r
-import org.simgrid.msg.Msg;\r
-\r
-/**\r
- * @author Andrea\r
- * \r
- */\r
-public class ChordProtocol implements EDProtocol {\r
-\r
- private static final String PAR_TRANSPORT = "transport";\r
-\r
- private Parameters p;\r
-\r
- private int[] lookupMessage;\r
-\r
- public int index = 0;\r
-\r
- public Node predecessor;\r
-\r
- public Node[] fingerTable;\r
-\r
- public Node[] successorList;\r
-\r
- public BigInteger chordId;\r
-\r
- public int m;\r
-\r
- public int succLSize;\r
-\r
- public String prefix;\r
-\r
- private int next = 0;\r
-\r
- // campo x debug\r
- private int currentNode = 0;\r
-\r
- public int varSuccList = 0;\r
-\r
- public int stabilizations = 0;\r
-\r
- public int fails = 0;\r
-\r
- /**\r
- * \r
- */\r
- public ChordProtocol(String prefix) {\r
- this.prefix = prefix;\r
- lookupMessage = new int[1];\r
- lookupMessage[0] = 0;\r
- p = new Parameters();\r
- p.tid = Configuration.getPid(prefix + "." + PAR_TRANSPORT);\r
- }\r
-\r
- /*\r
- * (non-Javadoc)\r
- * \r
- * @see peersim.edsim.EDProtocol#processEvent(peersim.core.Node, int,\r
- * java.lang.Object)\r
- */\r
- public void processEvent(Node node, int pid, Object event) {\r
- // processare le richieste a seconda della routing table del nodo\r
- p.pid = pid;\r
- // currentNode = node.getIndex();\r
- currentNode = (int) node.getID();\r
- if (event.getClass() == LookUpMessage.class) {\r
- LookUpMessage message = (LookUpMessage) event;\r
- message.increaseHopCounter();\r
- BigInteger target = message.getTarget();\r
- Transport t = (Transport) node.getProtocol(p.tid);\r
- Node n = message.getSender();\r
- System.out.println("R process " + "at time="\r
- + CommonState.getTime() + " to dest:" + currentNode\r
- + " from src:" + n.getID() + " message: ("\r
- + message.getSender().getID() + ";" + message.getTarget()\r
- + ")");\r
- if (target == ((ChordProtocol) node.getProtocol(pid)).chordId) {\r
- // mandare mess di tipo final\r
- Object msg = new FinalMessage(message.getHopCounter());\r
- System.out.println("S Final Message " + "at time="\r
- + CommonState.getTime() + " from src:" + node.getID()\r
- + " to dest:" + n.getID() + " message: "\r
- + message.getHopCounter() + " HopCounter");\r
- t.send(node, n, msg, pid);\r
-\r
- }\r
- if (target != ((ChordProtocol) node.getProtocol(pid)).chordId) {\r
- // funzione lookup sulla fingertabable\r
- Node dest = find_successor(target);\r
- if (dest.isUp() == false) {\r
- do {\r
- varSuccList = 0;\r
- stabilize(node);\r
- stabilizations++;\r
- fixFingers();\r
- dest = find_successor(target);\r
- } while (dest.isUp() == false);\r
- }\r
- if (dest.getID() == successorList[0].getID()\r
- && (target.compareTo(((ChordProtocol) dest\r
- .getProtocol(p.pid)).chordId) < 0)) {\r
- fails++;\r
- } else {\r
- System.out.println("S process " + "at time="\r
- + CommonState.getTime() + " from src:"\r
- + node.getID() + " to dest:" + dest.getID()\r
- + " message: (" + message.getSender().getID() + ";"\r
- + message.getTarget() + ")");\r
- // t.send(message.getSender(), dest, message, pid);\r
- t.send(node, dest, message, pid);\r
-\r
- }\r
- }\r
- }\r
- if (event.getClass() == FinalMessage.class) {\r
- FinalMessage message = (FinalMessage) event;\r
- System.out.println("R Final Message " + "at time="\r
- + CommonState.getTime() + " to dest:" + node.getID()+"\n");\r
- lookupMessage = new int[index + 1];\r
- lookupMessage[index] = message.getHopCounter();\r
- index++;\r
- }\r
- }\r
-\r
- public Object clone() {\r
- ChordProtocol cp = new ChordProtocol(prefix);\r
- String val = BigInteger.ZERO.toString();\r
- cp.chordId = new BigInteger(val);\r
- cp.fingerTable = new Node[m];\r
- cp.successorList = new Node[succLSize];\r
- cp.currentNode = 0;\r
- return cp;\r
- }\r
-\r
- public int[] getLookupMessage() {\r
- return lookupMessage;\r
- }\r
-\r
- public void stabilize(Node myNode) {\r
- try {\r
- Node node = ((ChordProtocol) successorList[0].getProtocol(p.pid)).predecessor;\r
- if (node != null) {\r
- if (this.chordId == ((ChordProtocol) node.getProtocol(p.pid)).chordId)\r
- return;\r
- BigInteger remoteID = ((ChordProtocol) node.getProtocol(p.pid)).chordId;\r
- if (idInab(\r
- remoteID,\r
- chordId,\r
- ((ChordProtocol) successorList[0].getProtocol(p.pid)).chordId))\r
- successorList[0] = node;\r
- ((ChordProtocol) successorList[0].getProtocol(p.pid))\r
- .notify(myNode);\r
- }\r
- updateSuccessorList();\r
- } catch (Exception e1) {\r
- e1.printStackTrace();\r
- updateSuccessor();\r
- }\r
- }\r
-\r
- private void updateSuccessorList() throws Exception {\r
- try {\r
- while (successorList[0] == null || successorList[0].isUp() == false) {\r
- updateSuccessor();\r
- }\r
- System.arraycopy(\r
- ((ChordProtocol) successorList[0].getProtocol(p.pid)).successorList,\r
- 0, successorList, 1, succLSize - 2);\r
- } catch (Exception e) {\r
- e.printStackTrace();\r
- }\r
- }\r
-\r
- public void notify(Node node) throws Exception {\r
- BigInteger nodeId = ((ChordProtocol) node.getProtocol(p.pid)).chordId;\r
- if ((predecessor == null)\r
- || (idInab(\r
- nodeId,\r
- ((ChordProtocol) predecessor.getProtocol(p.pid)).chordId,\r
- this.chordId))) {\r
- predecessor = node;\r
- }\r
- }\r
-\r
- private void updateSuccessor() {\r
- boolean searching = true;\r
- while (searching) {\r
- try {\r
- Node node = successorList[varSuccList];\r
- varSuccList++;\r
- successorList[0] = node;\r
- if (successorList[0] == null\r
- || successorList[0].isUp() == false) {\r
- if (varSuccList >= succLSize - 1) {\r
- searching = false;\r
- varSuccList = 0;\r
- } else\r
- updateSuccessor();\r
- }\r
- updateSuccessorList();\r
- searching = false;\r
- } catch (Exception e) {\r
- e.printStackTrace();\r
- }\r
- }\r
- }\r
-\r
- private boolean idInab(BigInteger id, BigInteger a, BigInteger b) {\r
- if ((a.compareTo(id) == -1) && (id.compareTo(b) == -1)) {\r
- return true;\r
- }\r
- return false;\r
- }\r
-\r
- public Node find_successor(BigInteger id) {\r
- try {\r
- if (successorList[0] == null || successorList[0].isUp() == false) {\r
- updateSuccessor();\r
- }\r
- if (idInab(\r
- id,\r
- this.chordId,\r
- ((ChordProtocol) successorList[0].getProtocol(p.pid)).chordId)) {\r
- return successorList[0];\r
- } else {\r
- Node tmp = closest_preceding_node(id);\r
- return tmp;\r
- }\r
- } catch (Exception e) {\r
- e.printStackTrace();\r
- }\r
- return successorList[0];\r
- }\r
-\r
- private Node closest_preceding_node(BigInteger id) {\r
- for (int i = m; i > 0; i--) {\r
- try {\r
- if (fingerTable[i - 1] == null\r
- || fingerTable[i - 1].isUp() == false) {\r
- continue;\r
- }\r
- BigInteger fingerId = ((ChordProtocol) (fingerTable[i - 1]\r
- .getProtocol(p.pid))).chordId;\r
- if ((idInab(fingerId, this.chordId, id))\r
- || (id.compareTo(fingerId) == 0)) {\r
- return fingerTable[i - 1];\r
- }\r
- if (fingerId.compareTo(this.chordId) == -1) {\r
- // sono nel caso in cui ho fatto un giro della rete\r
- // circolare\r
- if (idInab(id, fingerId, this.chordId)) {\r
- return fingerTable[i - 1];\r
- }\r
- }\r
- if ((id.compareTo(fingerId) == -1)\r
- && (id.compareTo(this.chordId) == -1)) {\r
- if (i == 1)\r
- return successorList[0];\r
- BigInteger lowId = ((ChordProtocol) fingerTable[i - 2]\r
- .getProtocol(p.pid)).chordId;\r
- if (idInab(id, lowId, fingerId))\r
- return fingerTable[i - 2];\r
- else if (fingerId.compareTo(this.chordId) == -1)\r
- continue;\r
- else if (fingerId.compareTo(this.chordId) == 1)\r
- return fingerTable[i - 1];\r
- }\r
- } catch (Exception e) {\r
- e.printStackTrace();\r
- }\r
- }\r
- if (fingerTable[m - 1] == null)\r
- return successorList[0];\r
- return successorList[0];\r
- }\r
-\r
- // debug function\r
- private void printFingers() {\r
- for (int i = fingerTable.length - 1; i > 0; i--) {\r
- if (fingerTable[i] == null) {\r
- System.out.println("Finger " + i + " is null");\r
- continue;\r
- }\r
- if ((((ChordProtocol) fingerTable[i].getProtocol(p.pid)).chordId)\r
- .compareTo(this.chordId) == 0)\r
- break;\r
- System.out\r
- .println("Finger["\r
- + i\r
- + "] = "\r
- + fingerTable[i].getIndex()\r
- + " chordId "\r
- + ((ChordProtocol) fingerTable[i]\r
- .getProtocol(p.pid)).chordId);\r
- }\r
- }\r
-\r
- public void fixFingers() {\r
- if (next >= m - 1)\r
- next = 0;\r
- if (fingerTable[next] != null && fingerTable[next].isUp()) {\r
- next++;\r
- return;\r
- }\r
- BigInteger base;\r
- if (next == 0)\r
- base = BigInteger.ONE;\r
- else {\r
- base = BigInteger.valueOf(2);\r
- for (int exp = 1; exp < next; exp++) {\r
- base = base.multiply(BigInteger.valueOf(2));\r
- }\r
- }\r
- BigInteger pot = this.chordId.add(base);\r
- BigInteger idFirst = ((ChordProtocol) Network.get(0).getProtocol(p.pid)).chordId;\r
- BigInteger idLast = ((ChordProtocol) Network.get(Network.size() - 1)\r
- .getProtocol(p.pid)).chordId;\r
- if (pot.compareTo(idLast) == 1) {\r
- pot = (pot.mod(idLast));\r
- if (pot.compareTo(this.chordId) != -1) {\r
- next++;\r
- return;\r
- }\r
- if (pot.compareTo(idFirst) == -1) {\r
- this.fingerTable[next] = Network.get(Network.size() - 1);\r
- next++;\r
- return;\r
- }\r
- }\r
- do {\r
- fingerTable[next] = ((ChordProtocol) successorList[0]\r
- .getProtocol(p.pid)).find_successor(pot);\r
- pot = pot.subtract(BigInteger.ONE);\r
- ((ChordProtocol) successorList[0].getProtocol(p.pid)).fixFingers();\r
- } while (fingerTable[next] == null || fingerTable[next].isUp() == false);\r
- next++;\r
- }\r
-\r
- /**\r
- */\r
- public void emptyLookupMessage() {\r
- index = 0;\r
- this.lookupMessage = new int[0];\r
- }\r
-}\r
+++ /dev/null
-/**\r
- * \r
- */\r
-package example.chord;\r
-\r
-import peersim.core.*;\r
-import peersim.config.Configuration;\r
-import java.math.*;\r
-\r
-/**\r
- * @author Andrea\r
- * \r
- */\r
-public class CreateNw implements Control {\r
-\r
- private int pid = 0;\r
-\r
- private static final String PAR_IDLENGTH = "idLength";\r
-\r
- private static final String PAR_PROT = "protocol";\r
-\r
- private static final String PAR_SUCCSIZE = "succListSize";\r
-\r
- int idLength = 0;\r
-\r
- int successorLsize = 0;\r
-\r
- int fingSize = 0;\r
- //campo x debug\r
- boolean verbose = false;\r
-\r
- /**\r
- * \r
- */\r
- public CreateNw(String prefix) {\r
- pid = Configuration.getPid(prefix + "." + PAR_PROT);\r
- idLength = Configuration.getInt(prefix + "." + PAR_IDLENGTH); \r
- successorLsize = Configuration.getInt(prefix + "." + PAR_SUCCSIZE); \r
- }\r
-\r
- /*\r
- * (non-Javadoc)\r
- * \r
- * @see peersim.core.Control#execute()\r
- */\r
-\r
- public boolean execute() {\r
- for (int i = 0; i < Network.size(); i++) {\r
- Node node = (Node) Network.get(i);\r
- ChordProtocol cp = (ChordProtocol) node.getProtocol(pid);\r
- cp.m = idLength;\r
- cp.succLSize = successorLsize;\r
- cp.varSuccList = 0;\r
- cp.chordId = new BigInteger(idLength, CommonState.r);\r
- cp.fingerTable = new Node[idLength];\r
- cp.successorList = new Node[successorLsize];\r
- }\r
- NodeComparator nc = new NodeComparator(pid);\r
- Network.sort(nc);\r
- createFingerTable();\r
- return false;\r
- }\r
-\r
- public Node findId(BigInteger id, int nodeOne, int nodeTwo) {\r
- if (nodeOne >= (nodeTwo - 1)) \r
- return Network.get(nodeOne);\r
- int middle = (nodeOne + nodeTwo) / 2;\r
- if (((middle) >= Network.size() - 1))\r
- System.out.print("ERROR: Middle is bigger than Network.size");\r
- if (((middle) <= 0))\r
- return Network.get(0);\r
- try {\r
- BigInteger newId = ((ChordProtocol) ((Node) Network.get(middle))\r
- .getProtocol(pid)).chordId;\r
- BigInteger lowId;\r
- if (middle > 0)\r
- lowId = ((ChordProtocol) ((Node) Network.get(middle - 1))\r
- .getProtocol(pid)).chordId;\r
- else\r
- lowId = newId;\r
- BigInteger highId = ((ChordProtocol) ((Node) Network\r
- .get(middle + 1)).getProtocol(pid)).chordId;\r
- if (id.compareTo(newId) == 0\r
- || ((id.compareTo(newId) == 1) && (id.compareTo(highId) == -1))) {\r
- return Network.get(middle);\r
- }\r
- if ((id.compareTo(newId) == -1) && (id.compareTo(lowId) == 1)) {\r
- if (middle > 0)\r
- return Network.get(middle - 1);\r
- else\r
- return Network.get(0);\r
- }\r
- if (id.compareTo(newId) == -1) {\r
- return findId(id, nodeOne, middle);\r
- } else if (id.compareTo(newId) == 1) {\r
- return findId(id, middle, nodeTwo);\r
- }\r
- return null;\r
- } catch (Exception e) {\r
- e.printStackTrace();\r
- return null;\r
- }\r
- }\r
-\r
- public void createFingerTable() {\r
- BigInteger idFirst = ((ChordProtocol) Network.get(0).getProtocol(pid)).chordId;\r
- BigInteger idLast = ((ChordProtocol) Network.get(Network.size() - 1)\r
- .getProtocol(pid)).chordId;\r
- for (int i = 0; i < Network.size(); i++) {\r
- Node node = (Node) Network.get(i);\r
- ChordProtocol cp = (ChordProtocol) node.getProtocol(pid);\r
- for (int a = 0; a < successorLsize; a++) {\r
- if (a + i < (Network.size() - 1))\r
- cp.successorList[a] = Network.get(a + i + 1);\r
- else\r
- cp.successorList[a] = Network.get(a);\r
- }\r
- if (i > 0)\r
- cp.predecessor = (Node) Network.get(i - 1);\r
- else\r
- cp.predecessor = (Node) Network.get(Network.size() - 1);\r
- int j = 0;\r
- for (j = 0; j < idLength; j++) {\r
- BigInteger base;\r
- if (j == 0)\r
- base = BigInteger.ONE;\r
- else {\r
- base = BigInteger.valueOf(2);\r
- for (int exp = 1; exp < j; exp++) {\r
- base = base.multiply(BigInteger.valueOf(2));\r
- }\r
- }\r
- BigInteger pot = cp.chordId.add(base);\r
- if (pot.compareTo(idLast) == 1) {\r
- pot = (pot.mod(idLast));\r
- if (pot.compareTo(cp.chordId) != -1) {\r
- break;\r
- }\r
- if (pot.compareTo(idFirst) == -1) {\r
- cp.fingerTable[j] = Network.get(Network.size() - 1);\r
- continue;\r
- }\r
- }\r
- cp.fingerTable[j] = findId(pot, 0, Network.size() - 1);\r
- }\r
- }\r
- }\r
-}\r
+++ /dev/null
-package example.chord;\r
-\r
-public class FinalMessage implements ChordMessage {\r
-\r
- private int hopCounter = 0;\r
-\r
- public FinalMessage(int hopCounter) {\r
- this.hopCounter = hopCounter;\r
- }\r
-\r
- public int getHopCounter() {\r
- return hopCounter;\r
- }\r
-}\r
+++ /dev/null
-package example.chord;\r
-\r
-import java.math.*;\r
-import peersim.core.*;\r
-\r
-public class LookUpMessage implements ChordMessage {\r
-\r
- private Node sender;\r
-\r
- private BigInteger targetId;\r
-\r
- private int hopCounter = -1;\r
-\r
- public LookUpMessage(Node sender, BigInteger targetId) {\r
- this.sender = sender;\r
- this.targetId = targetId;\r
- }\r
-\r
- public void increaseHopCounter() {\r
- hopCounter++;\r
- }\r
-\r
- /**\r
- * @return the senderId\r
- */\r
- public Node getSender() {\r
- return sender;\r
- }\r
-\r
- /**\r
- * @return the target\r
- */\r
- public BigInteger getTarget() {\r
- return targetId;\r
- }\r
-\r
- /**\r
- * @return the hopCounter\r
- */\r
- public int getHopCounter() {\r
- return hopCounter;\r
- }\r
-\r
-}\r
+++ /dev/null
-/**\r
- * \r
- */\r
-package example.chord;\r
-\r
-import java.util.ArrayList;\r
-import peersim.core.Control;\r
-import peersim.core.Network;\r
-import peersim.config.Configuration;\r
-\r
-/**\r
- * @author Andrea\r
- * \r
- */\r
-public class MessageCounterObserver implements Control {\r
-\r
- private static final String PAR_PROT = "protocol";\r
-\r
- private final String prefix;\r
-\r
- private final int pid;\r
-\r
- /**\r
- * \r
- */\r
- public MessageCounterObserver(String prefix) {\r
- this.prefix = prefix;\r
- this.pid = Configuration.getPid(prefix + "." + PAR_PROT);\r
- }\r
-\r
- /*\r
- * (non-Javadoc)\r
- * \r
- * @see peersim.core.Control#execute()\r
- */\r
- public boolean execute() {\r
- int size = Network.size();\r
- int totalStab = 0;\r
- int totFails = 0;\r
- ArrayList hopCounters = new ArrayList(); // struttura dati che\r
- // memorizza gli hop di\r
- // tutti i mess mandati\r
- hopCounters.clear();\r
- int max = 0;\r
- int min = Integer.MAX_VALUE;\r
- for (int i = 0; i < size; i++) {\r
- ChordProtocol cp = (ChordProtocol) Network.get(i).getProtocol(pid);\r
- // trovare tutti gli hopCOunter dei messaggi lookup mandati\r
- int[] counters = new int[cp.getLookupMessage().length];\r
- System.arraycopy(cp.getLookupMessage(), 0, counters, 0, cp\r
- .getLookupMessage().length);\r
- totalStab = totalStab + cp.stabilizations;\r
- totFails = totFails + cp.fails;\r
- cp.stabilizations = 0;\r
- cp.fails = 0;\r
- int maxNew = maxArray(counters, cp.index);\r
- if (maxNew > max)\r
- max = maxNew;\r
- if (cp.index != 0) {\r
- for (int j = 0; j < cp.index; j++)\r
- hopCounters.add(counters[j]);\r
- int minNew = minArray(counters, cp.index);\r
- if (minNew < min)\r
- min = minNew;\r
- }\r
- cp.emptyLookupMessage();\r
- }\r
- double media = meanCalculator(hopCounters);\r
- if (media > 0)\r
- System.out.println("Mean: " + media + " Max Value: " + max\r
- + " Min Value: " + min + " # Observations: "\r
- + hopCounters.size());\r
- System.out.println(" # Stabilizations: " + totalStab + " # Failures: "\r
- + totFails);\r
- System.out.println("");\r
- return false;\r
- }\r
-\r
- private double meanCalculator(ArrayList list) {\r
- int lenght = list.size();\r
- if (lenght == 0)\r
- return 0;\r
- int sum = 0;\r
- for (int i = 0; i < lenght; i++) {\r
- sum = sum + ((Integer) list.get(i)).intValue();\r
- }\r
- double mean = sum / lenght;\r
- return mean;\r
- }\r
-\r
- private int maxArray(int[] array, int dim) {\r
- int max = 0;\r
- for (int j = 0; j < dim; j++) {\r
- if (array[j] > max)\r
- max = array[j];\r
- }\r
- return max;\r
- }\r
-\r
- private int minArray(int[] array, int dim) {\r
- int min = 0;\r
- for (int j = 0; j < dim; j++) {\r
- if (array[j] < min)\r
- min = array[j];\r
- }\r
- return min;\r
- }\r
-}\r
+++ /dev/null
-package example.chord;\r
-\r
-import java.util.Comparator;\r
-import java.math.*;\r
-import peersim.core.*;\r
-\r
-public class NodeComparator implements Comparator {\r
-\r
- public int pid = 0;\r
-\r
- public NodeComparator(int pid) {\r
- this.pid = pid;\r
- }\r
-\r
- public int compare(Object arg0, Object arg1) {\r
- BigInteger one = ((ChordProtocol) ((Node) arg0).getProtocol(pid)).chordId;\r
- BigInteger two = ((ChordProtocol) ((Node) arg1).getProtocol(pid)).chordId;\r
- return one.compareTo(two);\r
- }\r
-\r
-}\r
+++ /dev/null
-package example.chord;\r
-\r
-public class Parameters {\r
- int pid;\r
-\r
- int tid;\r
-}\r
+++ /dev/null
-/**\r
- * \r
- */\r
-package example.chord;\r
-\r
-import org.simgrid.msg.Host;\r
-\r
-import peersim.core.*;\r
-import peersim.config.Configuration;\r
-import peersim.edsim.EDSimulator;\r
-import psgsim.PSGSimulator;\r
-\r
-/**\r
- * @author Andrea\r
- * \r
- */\r
-public class TrafficGenerator implements Control {\r
-\r
- private static final String PAR_PROT = "protocol";\r
-\r
- private final int pid;\r
-\r
- /**\r
- * \r
- */\r
- public TrafficGenerator(String prefix) {\r
- pid = Configuration.getPid(prefix + "." + PAR_PROT);\r
- }\r
-\r
- /*\r
- * (non-Javadoc)\r
- * \r
- * @see peersim.core.Control#execute()\r
- */\r
- public boolean execute() {\r
- int size = Network.size();\r
- Node sender, target;\r
- int i = 0;\r
- do {\r
- i++;\r
- sender = Network.get(CommonState.r.nextInt(size));\r
- target = Network.get(CommonState.r.nextInt(size));\r
- } while (sender == null || sender.isUp() == false || target == null\r
- || target.isUp() == false);\r
- LookUpMessage message = new LookUpMessage(sender,\r
- ((ChordProtocol) target.getProtocol(pid)).chordId);\r
- System.out.println("TrafficGenerator at time "+CommonState.getTime()+" Node:"\r
- + message.getSender().getID() +" target "+target.getID() + " pid:"\r
- + pid);\r
- EDSimulator.add(10, message, sender, pid);\r
- return false;\r
- }\r
-\r
-}\r
+++ /dev/null
-/*
- * Copyright (c) 2003 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 example.edaggregation;
-
-import peersim.vector.SingleValueHolder;
-import peersim.config.*;
-import peersim.core.*;
-import peersim.transport.Transport;
-import peersim.cdsim.CDProtocol;
-import peersim.edsim.EDProtocol;
-
-/**
- * Event driven version of epidemic averaging.
- */
-public class AverageED extends SingleValueHolder implements CDProtocol,
- EDProtocol {
-
- // --------------------------------------------------------------------------
- // Initialization
- // --------------------------------------------------------------------------
-
- /**
- * @param prefix
- * string prefix for config properties
- */
- public AverageED(String prefix) {
- super(prefix);
- }
-
- // --------------------------------------------------------------------------
- // methods
- // --------------------------------------------------------------------------
-
- /**
- * This is the standard method the define periodic activity. The frequency
- * of execution of this method is defined by a
- * {@link peersim.edsim.CDScheduler} component in the configuration.
- */
- public void nextCycle(Node node, int pid) {
- Linkable linkable = (Linkable) node.getProtocol(FastConfig
- .getLinkable(pid));
- if (linkable.degree() > 0) {
- int degree=linkable.degree();
- int i=CommonState.r.nextInt(degree);
- Node peern = linkable.getNeighbor(i);
- System.out.println("Pid of the protocol: "+pid);
- System.out.println("Time="+CommonState.getTime()+" degree="+degree+" i="+i+" peernID="+peern.getID()+" peernIndex="+peern.getIndex());
- if (!peern.isUp())
- return;
- AverageMessage ob=new AverageMessage(value, node);
- System.out.println("NextCycle\t"+"\t Time: " + CommonState.getTime()+ "\t src: " + node.getID() + "\t dst: " + peern.getID()+"\t msg:"+ob.value);
- ((Transport) node.getProtocol(FastConfig.getTransport(pid))).send(
- node, peern, ob, pid);
- }
- }
-
- // --------------------------------------------------------------------------
-
- /**
- * This is the standard method to define to process incoming messages.
- */
- public void processEvent(Node node, int pid, Object event) {
-
- AverageMessage aem = (AverageMessage) event;
-
- AverageMessage ob=null;
- if (aem.sender != null){
- System.out.println("ProcessEventR\t"+"\t Time: " + CommonState.getTime() + "\t src: " + aem.sender.getID() + "\t dst: " + node.getID()+"\t msg:"+aem.value);
- ob=new AverageMessage(value, null);
- System.out.println("ProcessEventS\t"+"\t Time: " + CommonState.getTime()+ "\t src: " + node.getID() + "\t dst: " + aem.sender.getID()+"\t msg:"+ob.value);
- ((Transport) node.getProtocol(FastConfig.getTransport(pid))).send(
- node, aem.sender, ob, pid);
- } else {
- System.out.println("ProcessEventR\t"+"\t Time: " +CommonState.getTime() + "\t src: " + "NULL" + "\t dst: " + node.getID()+"\t msg:"+aem.value);
- }
- value = (value + aem.value) / 2;
- }
-
-}
-
-// --------------------------------------------------------------------------
-// --------------------------------------------------------------------------
-
-/**
- * The type of a message. It contains a value of type double and the sender node
- * of type {@link peersim.core.Node}.
- */
-class AverageMessage {
-
- final double value;
- /**
- * If not null, this has to be answered, otherwise this is the answer.
- */
- final Node sender;
-
- public AverageMessage(double value, Node sender) {
- this.value = value;
- this.sender = sender;
- }
-}
\ No newline at end of file
+++ /dev/null
-package example.symphony;\r
-\r
-import java.util.Iterator;\r
-import peersim.core.Network;\r
-import peersim.core.Node;\r
-\r
-/**\r
- * Adapter Class absolutely UNSAFE, just to be able to iterate peersim.core.Network\r
- *\r
- * @author Andrea Esposito <and1989@gmail.com>\r
- */\r
-public class AdapterIterableNetwork implements Iterable<Node>, Iterator<Node> {\r
-\r
- private int i = 0;\r
-\r
- public Iterator<Node> iterator() {\r
- return this;\r
- }\r
-\r
- public boolean hasNext() {\r
- return i < Network.size();\r
- }\r
-\r
- public Node next() {\r
- return Network.get(i++);\r
- }\r
-\r
- public void remove() {\r
- throw new UnsupportedOperationException("Not supported yet.");\r
- }\r
-}\r
+++ /dev/null
-package example.symphony;\r
-\r
-import java.util.Comparator;\r
-\r
-import example.symphony.SymphonyProtocol.BootstrapStatus;\r
-import peersim.core.Node;\r
-\r
-/**\r
- * Object-Adapter\r
- *\r
- * @author Andrea Esposito <and1989@gmail.com>\r
- */\r
-public class AdapterSymphonyNodeComparator implements Comparator<Tuple<Node, BootstrapStatus>> {\r
-\r
- private SymphonyNodeComparator comparator;\r
-\r
- public AdapterSymphonyNodeComparator(SymphonyNodeComparator comparator) {\r
- this.comparator = comparator;\r
- }\r
-\r
- public int compare(Tuple<Node, BootstrapStatus> o1, Tuple<Node, BootstrapStatus> o2) {\r
-\r
- Node node1 = o1.x;\r
- Node node2 = o2.x;\r
-\r
- return comparator.compare(node1, node2);\r
- }\r
-}\r
+++ /dev/null
-package example.symphony;\r
-\r
-import peersim.core.Node;\r
-\r
-/**\r
- *\r
- * @author Andrea Esposito <and1989@gmail.com>\r
- */\r
-public interface Handler {\r
-\r
- /**\r
- * Handler associable to a routing request\r
- *\r
- * @param src Symphony Protocol that has sent the routing request\r
- * @param evt Tuple that contains: Node that manages the identifier, Identifier that the routing\r
- * has done on\r
- */\r
- void handle(SymphonyProtocol src, Tuple<Node, Double> evt);\r
-}\r
+++ /dev/null
-package example.symphony;\r
-\r
-import peersim.config.Configuration;\r
-import peersim.core.CommonState;\r
-import peersim.core.Control;\r
-import peersim.core.Network;\r
-import peersim.core.Node;\r
-\r
-/**\r
- *\r
- * @author Andrea Esposito <and1989@gmail.com>\r
- */\r
-public class LeaveTest implements Control {\r
-\r
- private static final String PAR_NETMANAGER = "symphonynetworkmanager";\r
- private static final String PAR_NUMBER_LEAVES = "n";\r
- private static final String PAR_MIN_SIZE = "minsizeOnline";\r
- private static final String PAR_WAIT_TARGET_SIZE = "waitTargetSizeToStart";\r
- private final int networkManagerID;\r
- private final double n;\r
- private final int minSizeNetwork;\r
- private int targetSize;\r
-\r
- public LeaveTest(String prefix) {\r
- networkManagerID = Configuration.getPid(prefix + "." + PAR_NETMANAGER);\r
- double nAppo = Configuration.getDouble(prefix + "." + PAR_NUMBER_LEAVES);\r
- if (!(nAppo > 0.0 && nAppo < 1.0)) {\r
- n = (int) Math.round(nAppo);\r
- } else {\r
- n = nAppo;\r
- }\r
-\r
- minSizeNetwork = Configuration.getInt(prefix + "." + PAR_MIN_SIZE, -1);\r
- targetSize = Configuration.getInt(prefix + "." + PAR_WAIT_TARGET_SIZE, -1);\r
- }\r
-\r
- public boolean execute() {\r
-\r
- if (minSizeNetwork > 0) {\r
-\r
- int onlineNode = 0;\r
- AdapterIterableNetwork it = new AdapterIterableNetwork();\r
- for (Node node : it) {\r
- if (node.isUp()) {\r
- onlineNode++;\r
- }\r
- }\r
-\r
- if (targetSize <= 0 || targetSize <= onlineNode) {\r
- targetSize = -1;\r
-\r
- // verify if i have to remove an exact number of nodes or a percentage of them\r
- int actualN = (int) (n < 1.0 ? Math.ceil(Network.size() * n) : n);\r
-\r
- for (int i = 0; i < actualN && Network.size() > 0; i++) {\r
- if (onlineNode > minSizeNetwork) {\r
- Node leaveNode = Network.get(Math.abs(CommonState.r.nextInt()) % Network.size());\r
-\r
- while (!leaveNode.isUp()) {\r
- leaveNode = Network.get(Math.abs(CommonState.r.nextInt()) % Network.size());\r
- }\r
-\r
- SymphonyNetworkManager networkManager = (SymphonyNetworkManager) leaveNode.getProtocol(networkManagerID);\r
-\r
- networkManager.leave(leaveNode);\r
-\r
- onlineNode--;\r
- } else {\r
- break;\r
- }\r
- }\r
- }\r
- }\r
-\r
- return false;\r
- }\r
-}\r
+++ /dev/null
-package example.symphony;\r
-\r
-import peersim.core.Node;\r
-\r
-/**\r
- *\r
- * @author Andrea Esposito <and1989@gmail.com>\r
- */\r
-public class Message implements Cloneable {\r
-\r
- public enum MessageType {\r
-\r
- ROUTE, ROUTE_RESPONSE, ROUTE_FAIL,\r
- JOIN, JOIN_RESPONSE,\r
- UPDATE_NEIGHBOURS, UPDATE_NEIGHBOURS_RESPONSE,\r
- REQUEST_LONG_RANGE_LINK, ACCEPTED_LONG_RANGE_LINK, REJECT_LONG_RANGE_LINK, DISCONNECT_LONG_RANGE_LINK, UNAVAILABLE_LONG_RANGE_LINK,\r
- UPDATE_STATUS, UPDATE_STATUS_RESPONSE,\r
- LEAVE,\r
- KEEP_ALIVE, KEEP_ALIVE_RESPONSE\r
- }\r
- private long hopCounter;\r
- private MessageType type;\r
- private Node src;\r
- private Node currentHop;\r
- private Object body;\r
- private static long globalID = 0;\r
- private final long id;\r
-\r
- public Message(Object body, Node src, MessageType type) {\r
- this.type = type;\r
- this.src = src;\r
- this.body = body;\r
- hopCounter = 0;\r
- id = globalID++;\r
- currentHop = src;\r
- }\r
-\r
- public long getID() {\r
- return id;\r
- }\r
-\r
- public Object getBody() {\r
- return body;\r
- }\r
-\r
- public void incrementHop() {\r
- hopCounter++;\r
- }\r
-\r
- public long getHop() {\r
- return hopCounter;\r
- }\r
-\r
- public MessageType getType() {\r
- return type;\r
- }\r
-\r
- public Node getSourceNode() {\r
- return src;\r
- }\r
-\r
- public Node getCurrentHop() {\r
- return currentHop;\r
- }\r
-\r
- public void setCurrentHop(Node currentHop) {\r
- this.currentHop = currentHop;\r
- }\r
-\r
- @Override\r
- public Object clone() throws CloneNotSupportedException {\r
- return super.clone();\r
- }\r
-\r
- @Override\r
- public String toString() {\r
-\r
- StringBuilder builder = new StringBuilder();\r
- builder.append("Message@").append(this.hashCode()).append("[\n");\r
-\r
- builder.append("\tID : ").append(id).append(",\n");\r
- builder.append("\tSource ID: ").append(src.getID()).append(",\n");\r
- builder.append("\tType : ").append(type).append(",\n");\r
- builder.append("\tBody : ").append(body).append(",\n");\r
- builder.append("\tCurrent Hop ID: ").append(currentHop.getID()).append(",\n");\r
- builder.append("\tHop Counter : ").append(hopCounter).append("\n]\n");\r
-\r
- return builder.toString();\r
- }\r
-}\r
+++ /dev/null
-package example.symphony;\r
-\r
-import peersim.core.Node;\r
-import peersim.core.Protocol;\r
-\r
-/**\r
- *\r
- * @author Andrea Esposito <and1989@gmail.com>\r
- */\r
-public interface NetworkSizeEstimatorProtocolInterface extends Protocol {\r
-\r
- public int getNetworkSize(Node node);\r
-}\r
+++ /dev/null
-package example.symphony;\r
-\r
-import java.util.logging.Level;\r
-import java.util.logging.Logger;\r
-import peersim.config.Configuration;\r
-import peersim.core.CommonState;\r
-import peersim.core.Control;\r
-import peersim.core.Network;\r
-import peersim.core.Node;\r
-\r
-/**\r
- *\r
- * @author Andrea Esposito <and1989@gmail.com>\r
- */\r
-public class RandomRouteTest implements Control, Handler {\r
-\r
- private static final String PAR_SYMPHONY = "symphony";\r
- private final int symphonyID;\r
-\r
- public RandomRouteTest(String prefix) {\r
- symphonyID = Configuration.getPid(prefix + "." + PAR_SYMPHONY);\r
- }\r
-\r
- public boolean execute() {\r
-\r
- Node src = Network.get(Math.abs(CommonState.r.nextInt()) % Network.size());\r
-\r
- SymphonyProtocol symphony = (SymphonyProtocol) src.getProtocol(symphonyID);\r
- try {\r
- symphony.route(src, CommonState.r.nextDouble(), this);\r
- } catch (RoutingException ex) {\r
- Logger.getLogger(RandomRouteTest.class.getName()).log(Level.SEVERE, ex.getMessage());\r
- }\r
-\r
- return false;\r
-\r
- }\r
-\r
- public void handle(SymphonyProtocol symphony, Tuple<Node, Double> tuple) {\r
-\r
- if (tuple == null) {\r
- Logger.getLogger(RandomRouteTest.class.getName()).log(Level.SEVERE, "FAIL ROUTE RANDOMTEST");\r
- return;\r
- }\r
-\r
- Logger.getLogger(RandomRouteTest.class.getName()).log(Level.FINE, symphony.getIdentifier() + " source find the manager of " + tuple.y + " and it is " + ((SymphonyProtocol) tuple.x.getProtocol(symphonyID)).getIdentifier());\r
- }\r
-}\r
+++ /dev/null
-package example.symphony;\r
-\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-import java.util.HashSet;\r
-import java.util.LinkedList;\r
-import java.util.logging.Level;\r
-import java.util.logging.Logger;\r
-\r
-import example.symphony.SymphonyProtocol.BootstrapStatus;\r
-import peersim.config.Configuration;\r
-import peersim.core.Control;\r
-import peersim.core.Network;\r
-import peersim.core.Node;\r
-\r
-/**\r
- *\r
- * @author Andrea Esposito <and1989@gmail.com>\r
- */\r
-public class RingRouteTest implements Control, Handler {\r
-\r
- private static final String PAR_SYMPHONY = "symphony";\r
- private static final String PAR_STARTNODE = "startnode";\r
- private final int symphonyID;\r
- private final int indexStartNode;\r
- private Node start;\r
- private boolean finished;\r
- private boolean flagTimeout;\r
- private HashSet<Node> antiLoopSet;\r
-\r
- public RingRouteTest(String prefix) {\r
- symphonyID = Configuration.getPid(prefix + "." + PAR_SYMPHONY);\r
- indexStartNode = Configuration.getInt(prefix + "." + PAR_STARTNODE, 0);\r
-\r
- finished = true;\r
- flagTimeout = false;\r
- antiLoopSet = new HashSet<Node>();\r
- }\r
-\r
- public boolean execute() {\r
-\r
- if (!finished && flagTimeout) {\r
-\r
- Logger.getLogger(RingRouteTest.class.getName()).log(Level.WARNING, "Sent msg but no aswer. Timeout. Ring Route Test terminated for Timeout.");\r
-\r
- finished = true;\r
- flagTimeout = false;\r
- }\r
-\r
- if (finished) {\r
-\r
- flagTimeout = true;\r
- antiLoopSet.clear();\r
-\r
- int indexRealStartNode = indexStartNode;\r
- Node realStartNode = Network.get(indexStartNode);\r
- SymphonyProtocol symphony = (SymphonyProtocol) realStartNode.getProtocol(symphonyID);\r
-\r
- while (!symphony.isBootstrapped() || !realStartNode.isUp()) {\r
- indexRealStartNode = (indexRealStartNode + 1) % Network.size();\r
- realStartNode = Network.get(indexRealStartNode);\r
- symphony = (SymphonyProtocol) realStartNode.getProtocol(symphonyID);\r
-\r
- if (indexRealStartNode == indexStartNode) {\r
- Logger.getLogger(RingRouteTest.class.getName()).log(Level.WARNING, "No ONLINE nodes. The ring is vanished. Ring Route Terminated.");\r
- finished = true;\r
- flagTimeout = false;\r
- return false;\r
- }\r
- }\r
-\r
- start = realStartNode;\r
- finished = false;\r
-\r
- Logger.getLogger(RingRouteTest.class.getName()).log(Level.INFO, "RingRoute started.");\r
-\r
- doRoute(start, true);\r
- }\r
-\r
- return false;\r
- }\r
-\r
- public void handle(SymphonyProtocol symphony, Tuple<Node, Double> tuple) {\r
-\r
- if (tuple == null) {\r
- Logger.getLogger(RingRouteTest.class.getName()).log(Level.SEVERE, "FAIL RING ROUTING");\r
- finished = true;\r
- return;\r
- }\r
-\r
- Logger.getLogger(RingRouteTest.class.getName()).log(Level.FINER, symphony.getIdentifier() + " source find the manager of " + tuple.y + " and it is " + ((SymphonyProtocol) tuple.x.getProtocol(symphonyID)).getIdentifier());\r
-\r
- doRoute(tuple.x, false);\r
- }\r
-\r
- private void doRoute(Node node, boolean firstTime) {\r
-\r
- SymphonyProtocol symphonyStartNode = (SymphonyProtocol) start.getProtocol(symphonyID);\r
-\r
- if (!symphonyStartNode.isBootstrapped()) {\r
- Logger.getLogger(RingRouteTest.class.getName()).log(Level.INFO, "The node i started from left. Ring Route Terminated.");\r
- finished = true;\r
- return;\r
- }\r
-\r
- if (!firstTime && node.equals(start)) {\r
- Logger.getLogger(RingRouteTest.class.getName()).log(Level.INFO, "RingRoute Terminated");\r
- finished = true;\r
- return;\r
- }\r
-\r
- if (antiLoopSet.contains(node)) {\r
- Logger.getLogger(RingRouteTest.class.getName()).log(Level.INFO, "Not able to reach the node that i started from. Ring Route Terminated.");\r
- finished = true;\r
- return;\r
- } else {\r
- antiLoopSet.add(node);\r
- }\r
-\r
- SymphonyProtocol symphony = (SymphonyProtocol) node.getProtocol(symphonyID);\r
- AdapterSymphonyNodeComparator adapterSymphonyNodeComparator = new AdapterSymphonyNodeComparator(new SymphonyNodeComparator(symphonyID, node));\r
-\r
- Collection<Tuple<Node, BootstrapStatus>> collection = (Collection<Tuple<Node, BootstrapStatus>>) symphony.leftShortRangeLinks.clone();\r
- LinkedList<Tuple<Node, BootstrapStatus>> list = new LinkedList<Tuple<Node, BootstrapStatus>>(collection);\r
- Collections.sort(list, adapterSymphonyNodeComparator);\r
-\r
- Node targetNode = null;\r
- for (Tuple<Node, BootstrapStatus> tuple : list) {\r
- if (tuple.y == BootstrapStatus.ONLINE) {\r
- targetNode = tuple.x;\r
- break;\r
- }\r
- }\r
-\r
- if (targetNode == null || !targetNode.isUp()) {\r
- Logger.getLogger(RingRouteTest.class.getName()).log(Level.WARNING, "Terminated Ring Route but not done completely");\r
- finished = true;\r
- return;\r
- }\r
-\r
- SymphonyProtocol symphonyTarget = (SymphonyProtocol) targetNode.getProtocol(symphonyID);\r
- try {\r
- symphony.route(node, symphonyTarget.getIdentifier(), this);\r
- Logger.getLogger(RingRouteTest.class.getName()).log(Level.FINEST, "Ring from: " + symphony.getIdentifier() + " to " + symphonyTarget.getIdentifier());\r
- } catch (RoutingException ex) {\r
- Logger.getLogger(RingRouteTest.class.getName()).log(Level.WARNING, "Finito AnelloRoute MA NON FATTO TUTTO");\r
- finished = true;\r
- }\r
- }\r
-}\r
+++ /dev/null
-package example.symphony;\r
-\r
-/**\r
- *\r
- * @author Andrea Esposito <and1989@gmail.com>\r
- */\r
-public class RoutingException extends Exception {\r
-\r
- public RoutingException() {\r
- }\r
-\r
- public RoutingException(String msg) {\r
- super(msg);\r
- }\r
-}\r
+++ /dev/null
-package example.symphony;\r
-\r
-import peersim.core.Network;\r
-import peersim.core.Node;\r
-\r
-/**\r
- *\r
- * @author Andrea Esposito <and1989@gmail.com>\r
- */\r
-public class SimpleNetworkSizeEstimatorProtocol implements NetworkSizeEstimatorProtocolInterface {\r
-\r
- public SimpleNetworkSizeEstimatorProtocol(String prefix) {\r
- }\r
-\r
- public int getNetworkSize(Node node) {\r
- return Network.size();\r
- }\r
-\r
- @Override\r
- public Object clone() {\r
- return this;\r
- }\r
-}\r
+++ /dev/null
-package example.symphony;\r
-\r
-import java.util.*;\r
-import peersim.config.Configuration;\r
-import peersim.core.Network;\r
-import peersim.core.Node;\r
-\r
-/**\r
- *\r
- * @author Andrea Esposito <and1989@gmail.com>\r
- */\r
-public class SymphonyEstimationProtocol implements NetworkSizeEstimatorProtocolInterface {\r
-\r
- private static final String PAR_SYMPHONY = "symphony";\r
- private static final String PAR_S = "s";\r
- private final int symphonyID;\r
- private final int s;\r
-\r
- public SymphonyEstimationProtocol(String prefix) {\r
- symphonyID = Configuration.getPid(prefix + "." + PAR_SYMPHONY);\r
- s = Configuration.getInt(prefix + "." + PAR_S, -1);\r
- }\r
-\r
- /**\r
- * Implementation of the estimated network size as a variant of the paper one. It use anyway the\r
- * idea to calculate the size from the length segments but without exchanging the information\r
- * with the neighbours instead using only the local information.\r
- */\r
- public int getNetworkSize(Node node) {\r
- SymphonyProtocol symphony = (SymphonyProtocol) node.getProtocol(symphonyID);\r
-\r
- // If the node is not yet inside the ring i return the minimum size (2 nodes)\r
- if (!symphony.isBootstrapped()) {\r
- return 2;\r
- }\r
-\r
- /*\r
- * I clone the short range links views (wrapped into an ArrayList because the returned list\r
- * 'Arrays.asList doesn't support the "removeAll" method or better its size is fixed)\r
- */\r
- ArrayList<Tuple<Node, SymphonyProtocol.BootstrapStatus>> leftList = new ArrayList<Tuple<Node, SymphonyProtocol.BootstrapStatus>>(Arrays.asList((Tuple<Node, SymphonyProtocol.BootstrapStatus>[]) symphony.leftShortRangeLinks.toArray(new Tuple[0])));\r
- ArrayList<Tuple<Node, SymphonyProtocol.BootstrapStatus>> rightList = new ArrayList<Tuple<Node, SymphonyProtocol.BootstrapStatus>>(Arrays.asList((Tuple<Node, SymphonyProtocol.BootstrapStatus>[]) symphony.rightShortRangeLinks.toArray(new Tuple[0])));\r
-\r
- // Remove the neighbours that are offline\r
- LinkedList<Tuple<Node, SymphonyProtocol.BootstrapStatus>> offlineNeighbors = new LinkedList<Tuple<Node, SymphonyProtocol.BootstrapStatus>>();\r
- for (Tuple<Node, SymphonyProtocol.BootstrapStatus> tuple : leftList) {\r
- if (tuple.y == SymphonyProtocol.BootstrapStatus.OFFLINE) {\r
- offlineNeighbors.add(tuple);\r
- }\r
- }\r
- leftList.removeAll(offlineNeighbors);\r
- offlineNeighbors.clear();\r
- for (Tuple<Node, SymphonyProtocol.BootstrapStatus> tuple : rightList) {\r
- if (tuple.y == SymphonyProtocol.BootstrapStatus.OFFLINE) {\r
- offlineNeighbors.add(tuple);\r
- }\r
- }\r
- rightList.removeAll(offlineNeighbors);\r
-\r
- // Sort the neighbours based on the distance from me\r
- Comparator<Tuple<Node, SymphonyProtocol.BootstrapStatus>> comparator = new AdapterSymphonyNodeComparator(new SymphonyNodeComparator(symphonyID, symphony.getIdentifier()));\r
- Collections.sort(leftList, comparator);\r
- Collections.sort(rightList, comparator);\r
-\r
- // Calculate the variables to estimated the network size\r
- double Xs = 0;\r
- int countS = 0;\r
-\r
- List<Tuple<Node, SymphonyProtocol.BootstrapStatus>> appoList[] = new List[2];\r
- appoList[0] = leftList;\r
- appoList[1] = rightList;\r
-\r
- double[] appoPrecIdentifier = new double[]{symphony.getIdentifier(), symphony.getIdentifier()};\r
- int[] appoCurrentIndex = new int[]{0, 0};\r
-\r
- int realS = (int) (s <= 0 ? Math.log(Network.size() / Math.log(2)) : s);\r
-\r
- for (int i = 0; i < realS; i++) {\r
- double precIdentifier = appoPrecIdentifier[i % 2];\r
- int currentIndex = appoCurrentIndex[i % 2];\r
- List<Tuple<Node, SymphonyProtocol.BootstrapStatus>> currentList = appoList[i % 2];\r
-\r
- try {\r
- double currentIdentifier = ((SymphonyProtocol) currentList.get(currentIndex).x.getProtocol(symphonyID)).getIdentifier();\r
-\r
- appoPrecIdentifier[i % 2] = currentIdentifier;\r
- appoCurrentIndex[i % 2] = appoCurrentIndex[i % 2] + 1;\r
-\r
- double distance = Math.abs(currentIdentifier - precIdentifier);\r
- Xs += Math.min(distance, 1.0 - distance);\r
- countS++;\r
- } catch (IndexOutOfBoundsException ex) {\r
- // Simply i skip the counting\r
- }\r
- }\r
-\r
- int ret = Xs == 0 ? 0 : (int) Math.round(countS / Xs);\r
-\r
- return ret;\r
- }\r
-\r
- @Override\r
- public Object clone() {\r
- return this;\r
- }\r
-}\r
+++ /dev/null
-package example.symphony;\r
-\r
-import java.util.Collection;\r
-import java.util.Comparator;\r
-import java.util.LinkedList;\r
-import java.util.logging.Level;\r
-import java.util.logging.Logger;\r
-\r
-import example.symphony.SymphonyProtocol.BootstrapStatus;\r
-import peersim.config.Configuration;\r
-import peersim.core.CommonState;\r
-import peersim.core.Control;\r
-import peersim.core.Network;\r
-import peersim.core.Node;\r
-\r
-/**\r
- * Inizializer that create the initial ring\r
- *\r
- * @author Andrea Esposito <and1989@gmail.com>\r
- */\r
-public class SymphonyNetworkBuilder implements Control {\r
-\r
- private static final String PAR_SYMHONY = "symphony";\r
- private static final String PAR_LONG_LINK = "createLongLinks";\r
- private static final String PAR_MAX_ATTEMPTS = "attempts";\r
- private final int symphonyID;\r
- private final boolean createLongRangeLinks;\r
- private final int MAX_ATTEMPTS;\r
-\r
- public SymphonyNetworkBuilder(String prefix) {\r
-\r
- symphonyID = Configuration.getPid(prefix + "." + PAR_SYMHONY);\r
- createLongRangeLinks = Configuration.getBoolean(prefix + "." + PAR_LONG_LINK, true);\r
- MAX_ATTEMPTS = Configuration.getInt(prefix + "." + PAR_MAX_ATTEMPTS, 5);\r
- }\r
-\r
- public boolean execute() {\r
-\r
- // Sort the network for convenience (from 0.0 to 1.0)\r
- Network.sort(new Comparator<Node>() {\r
-\r
- public int compare(Node o1, Node o2) {\r
-\r
- SymphonyProtocol symphony1 = (SymphonyProtocol) o1.getProtocol(symphonyID);\r
- SymphonyProtocol symphony2 = (SymphonyProtocol) o2.getProtocol(symphonyID);\r
-\r
- Double identifier1 = symphony1.getIdentifier();\r
- Double identifier2 = symphony2.getIdentifier();\r
-\r
- return identifier1.compareTo(identifier2);\r
- }\r
- });\r
-\r
- int numShortLinksPerSide = ((SymphonyProtocol) Network.get(0).getProtocol(symphonyID)).numberShortRangeLinksPerSide;\r
-\r
- for (int i = 0; i < Network.size(); i++) {\r
-\r
- Node node = Network.get(i);\r
- SymphonyProtocol symphonyNode = (SymphonyProtocol) node.getProtocol(symphonyID);\r
-\r
- // Create the short links\r
- for (int j = 1; j <= numShortLinksPerSide; j++) {\r
-\r
- int pos = i - j;\r
- pos = pos < 0 ? Network.size() + pos : pos;\r
- symphonyNode.rightShortRangeLinks.add(new Tuple<Node, BootstrapStatus>(Network.get(pos), BootstrapStatus.ONLINE));\r
-\r
- pos = (i + j) % Network.size();\r
- symphonyNode.leftShortRangeLinks.add(new Tuple<Node, BootstrapStatus>(Network.get(pos), BootstrapStatus.ONLINE));\r
- }\r
-\r
- symphonyNode.loggedIntoNetwork = SymphonyProtocol.BootstrapStatus.ONLINE;\r
- }\r
-\r
- /*\r
- * UPDATE: Putted a flag to decide if perform this part of code or not at configuration\r
- * time. At default i create the long range links.\r
- *\r
- * The Long Range Links could be left to the networkmanager but the tests that we'll do have\r
- * to put into account that in an initial phase will be some message exchanging to create\r
- * the long range links and so the latency is faked... for that reason the long range links\r
- * are created manually here such a way to have a complete symphony network from the\r
- * beginning.\r
- */\r
- if (createLongRangeLinks) {\r
- for (Node node : new AdapterIterableNetwork()) {\r
-\r
- SymphonyProtocol symphonyNode = (SymphonyProtocol) node.getProtocol(symphonyID);\r
-\r
- // Create the long links\r
- int k = (int) Math.ceil(Math.log(Network.size()) / Math.log(2));\r
-\r
- if (symphonyNode.fixedLongRangeLinks) {\r
- k = symphonyNode.numberFixedLongRangeLinks;\r
- }\r
-\r
- Collection<Node> allShortLinks = new LinkedList<Node>();\r
- for (Tuple<Node, BootstrapStatus> shortTuple : symphonyNode.leftShortRangeLinks) {\r
- allShortLinks.add(shortTuple.x);\r
- }\r
- for (Tuple<Node, BootstrapStatus> shortTuple : symphonyNode.rightShortRangeLinks) {\r
- allShortLinks.add(shortTuple.x);\r
- }\r
-\r
- int j = 0;\r
- int attempts = MAX_ATTEMPTS;\r
- while (j <= k) {\r
-\r
- double distance = Math.exp(k * (CommonState.r.nextDouble() - 1.0));\r
- double targetIdentifier = (symphonyNode.getIdentifier() + distance) % 1;\r
-\r
- Node targetNode;\r
- try {\r
-\r
- // use the unidirectional routing because i want to catch the manager\r
- targetNode = symphonyNode.findClosestNode(targetIdentifier, new AdapterIterableNetwork(), true);\r
- SymphonyProtocol symphonyTargetNode = (SymphonyProtocol) targetNode.getProtocol(symphonyID);\r
- if (!targetNode.equals(node)\r
- && !symphonyNode.longRangeLinksOutgoing.contains(targetNode)\r
- && symphonyTargetNode.longRangeLinksIncoming.size() < (2 * k)\r
- && !allShortLinks.contains(targetNode)) {\r
-\r
- boolean fresh = symphonyTargetNode.longRangeLinksIncoming.add(node);\r
-\r
- if (fresh) {\r
- j++;\r
- attempts = MAX_ATTEMPTS;\r
- symphonyNode.longRangeLinksOutgoing.add(targetNode);\r
- } else {\r
- attempts--;\r
- if (attempts <= 0) { // Because i don't want to loop i try a finite number of times\r
- attempts = MAX_ATTEMPTS;\r
- j++;\r
- }\r
-\r
- }\r
- } else {\r
- attempts--;\r
- if (attempts <= 0) { // Because i don't want to loop i try a finite number of times\r
- attempts = MAX_ATTEMPTS;\r
- j++;\r
- }\r
-\r
- }\r
- } catch (RoutingException ex) {\r
- Logger.getLogger(SymphonyNetworkBuilder.class.getName()).log(Level.SEVERE, null, ex);\r
- }\r
- }\r
- }\r
- }\r
-\r
- // Shuffle\r
- Network.shuffle();\r
-\r
- return false;\r
- }\r
-}\r
+++ /dev/null
-package example.symphony;\r
-\r
-import java.util.Collections;\r
-import java.util.HashSet;\r
-import java.util.Set;\r
-import java.util.logging.Level;\r
-import java.util.logging.Logger;\r
-\r
-import example.symphony.SymphonyProtocol.BootstrapStatus;\r
-import peersim.config.Configuration;\r
-import peersim.core.Control;\r
-import peersim.core.Network;\r
-import peersim.core.Node;\r
-\r
-/**\r
- *\r
- * @author Andrea Esposito <and1989@gmail.com>\r
- */\r
-public class SymphonyNetworkChecker implements Control {\r
-\r
- private static final String PAR_SYMHONY = "symphony";\r
- private static final String PAR_NETSIZE = "networkestimator";\r
- private final int symphonyID;\r
- private final int networkEstimatorID;\r
-\r
- public SymphonyNetworkChecker(String prefix) {\r
- symphonyID = Configuration.getPid(prefix + "." + PAR_SYMHONY);\r
- networkEstimatorID = Configuration.getPid(prefix + "." + PAR_NETSIZE);\r
- }\r
-\r
- public boolean execute() {\r
-\r
- boolean isNotOK = false;\r
-\r
- Set<Double> idSet = new HashSet<Double>();\r
- Iterable<Node> coll = new AdapterIterableNetwork();\r
-\r
- int countOnline = 0;\r
- int count = 0;\r
- int notBootstrapped = 0;\r
- int countKO = 0;\r
- int disconnected = 0;\r
-\r
- for (Node node : coll) {\r
- SymphonyProtocol symphony = (SymphonyProtocol) node.getProtocol(symphonyID);\r
-\r
- if (!node.isUp()) {\r
- disconnected++;\r
- } else {\r
- count++;\r
- }\r
-\r
- if (symphony.loggedIntoNetwork == SymphonyProtocol.BootstrapStatus.ONLINE) {\r
-\r
- countOnline++;\r
-\r
- NetworkSizeEstimatorProtocolInterface networkEstimator = (NetworkSizeEstimatorProtocolInterface) node.getProtocol(networkEstimatorID);\r
- int k = (int) Math.ceil(Math.log(networkEstimator.getNetworkSize(node)) / Math.log(2));\r
-\r
- boolean checkLeftShortRangeLinks = symphony.leftShortRangeLinks.size() > 0 && symphony.leftShortRangeLinks.size() <= symphony.numberShortRangeLinksPerSide;\r
- boolean checkRightShortRangeLinks = symphony.rightShortRangeLinks.size() > 0 && symphony.rightShortRangeLinks.size() <= symphony.numberShortRangeLinksPerSide;\r
-\r
- boolean oneNeighborOnline = false;\r
- for (Tuple<Node, BootstrapStatus> leftTuple : symphony.leftShortRangeLinks) {\r
- if (leftTuple.y != BootstrapStatus.ONLINE && leftTuple.y != BootstrapStatus.OFFLINE) {\r
- notBootstrapped++;\r
- } else {\r
- oneNeighborOnline = true;\r
- checkLeftShortRangeLinks = checkLeftShortRangeLinks && SymphonyProtocol.isLeftNeighbour(node, leftTuple.x);\r
- }\r
- }\r
- checkLeftShortRangeLinks = checkLeftShortRangeLinks && oneNeighborOnline;\r
-\r
- oneNeighborOnline = false;\r
- for (Tuple<Node, BootstrapStatus> rightTuple : symphony.rightShortRangeLinks) {\r
- if (rightTuple.y != BootstrapStatus.ONLINE && rightTuple.y != BootstrapStatus.OFFLINE) {\r
- notBootstrapped++;\r
- } else {\r
- oneNeighborOnline = true;\r
- checkRightShortRangeLinks = checkRightShortRangeLinks && !SymphonyProtocol.isLeftNeighbour(node, rightTuple.x);\r
- }\r
- }\r
- checkRightShortRangeLinks = checkRightShortRangeLinks && oneNeighborOnline;\r
-\r
- // Check if the node is in its neighbours\r
- if (checkLeftShortRangeLinks) {\r
- AdapterSymphonyNodeComparator comparator = new AdapterSymphonyNodeComparator(new SymphonyNodeComparator(symphonyID, node));\r
- checkLeftShortRangeLinks = checkLeftShortRangeLinks && !Collections.min(symphony.leftShortRangeLinks, comparator).x.equals(node);\r
- }\r
-\r
- if (checkRightShortRangeLinks) {\r
- AdapterSymphonyNodeComparator comparator = new AdapterSymphonyNodeComparator(new SymphonyNodeComparator(symphonyID, node));\r
- checkRightShortRangeLinks = checkRightShortRangeLinks && !Collections.min(symphony.rightShortRangeLinks, comparator).x.equals(node);\r
- }\r
-\r
- boolean checkLongRangeLinksOutgoing = !symphony.longRangeLinksOutgoing.contains(node);\r
- boolean checkLongRangeLinksIncoming = /*\r
- * symphony.longRangeLinksIncoming.size() <= (2 * k) &&\r
- */ !symphony.longRangeLinksIncoming.contains(node);\r
-\r
- boolean checkUniqueID = !idSet.contains(symphony.getIdentifier());\r
- idSet.add(symphony.getIdentifier());\r
-\r
- boolean nextIsNotOK = !(checkUniqueID && checkLeftShortRangeLinks && checkRightShortRangeLinks && checkLongRangeLinksOutgoing && checkLongRangeLinksIncoming);\r
-\r
- if (nextIsNotOK) {\r
- countKO++;\r
- Logger.getLogger(SymphonyNetworkChecker.class.getName()).log(Level.SEVERE, "OPS");\r
- }\r
-\r
- isNotOK = isNotOK || nextIsNotOK;\r
- }\r
- }\r
-\r
- System.out.println("Error: " + countKO);\r
- System.out.println("Online: " + countOnline + "/" + count);\r
- System.out.println("Not Bootstrapped: " + notBootstrapped);\r
- System.out.println("Disconnected: " + disconnected);\r
- System.out.println("Network Size: " + Network.size());\r
-\r
- return isNotOK;\r
- }\r
-}\r
+++ /dev/null
-package example.symphony;\r
-\r
-import java.util.*;\r
-import java.util.logging.Level;\r
-import java.util.logging.Logger;\r
-\r
-import example.symphony.Message.MessageType;\r
-import example.symphony.SymphonyProtocol.BootstrapStatus;\r
-import peersim.cdsim.CDProtocol;\r
-import peersim.config.Configuration;\r
-import peersim.core.CommonState;\r
-import peersim.core.Fallible;\r
-import peersim.core.Node;\r
-import peersim.edsim.EDProtocol;\r
-import peersim.transport.Transport;\r
-\r
-/**\r
- *\r
- * @author Andrea Esposito <and1989@gmail.com>\r
- */\r
-public class SymphonyNetworkManager implements EDProtocol, CDProtocol {\r
-\r
- private static final String PAR_SYMPHONY = "symphony";\r
- private static final String PAR_TRANSP = "transport";\r
- private static final String PAR_ATTEMPTS = "attempts";\r
- private static final String PAR_NETSIZE = "networkestimator";\r
- private static final String PAR_NUM_TIMEOUT = "nTimeout";\r
- private static final String PAR_RELINKING = "relinking";\r
- private static final String PAR_RELINKING_LOWER_BOUND = "relinkingLowerBound";\r
- private static final String PAR_RELINKING_UPPER_BOUND = "relinkingUpperBound";\r
- private static final int DEFAULT_K = 1;\r
- private static final int DEFAULT_N = 2;\r
- private static final double DEFAULT_RELINKING_LOWER_BOUND = 0.5;\r
- private static final double DEFAULT_RELINKING_UPPER_BOUND = 2.0;\r
- private final String prefix;\r
- private final int symphonyID;\r
- private final int transportID;\r
- private final int networkEstimatorID;\r
- private final int attempts;\r
- private final int pid;\r
- private final int nTimeout;\r
- private final HashMap<Node, Integer> keepAliveMap;\r
- private final boolean relinkingProtocolActivated;\r
- private final double relinkingUpperBound;\r
- private final double relinkingLowerBound;\r
- private int k = DEFAULT_K; // Number of Long Range Link\r
- private int n = DEFAULT_N; // Estimation Network size\r
- private static boolean firstPrintConfig = true;\r
- /*\r
- * Estimation Network size at which last long distance link was established, at the beginning -1\r
- * to indicate that we never had Long Range Links\r
- */\r
- private int nLink = -1;\r
- private int currentAttempts;\r
-\r
- public SymphonyNetworkManager(String prefix) {\r
-\r
- this.prefix = prefix;\r
- pid = Configuration.lookupPid(prefix.replaceAll("protocol.", ""));\r
- symphonyID = Configuration.getPid(prefix + "." + PAR_SYMPHONY);\r
- transportID = Configuration.getPid(prefix + "." + PAR_TRANSP);\r
- networkEstimatorID = Configuration.getPid(prefix + "." + PAR_NETSIZE);\r
- attempts = Configuration.getInt(prefix + "." + PAR_ATTEMPTS);\r
- nTimeout = Configuration.getInt(prefix + "." + PAR_NUM_TIMEOUT, 10);\r
- relinkingProtocolActivated = !Configuration.getString(prefix + "." + PAR_RELINKING, "on").toLowerCase().equals("off");\r
- double relinkingLowerBoundAppo = Configuration.getDouble(prefix + "." + PAR_RELINKING_LOWER_BOUND, DEFAULT_RELINKING_LOWER_BOUND);\r
- double relinkingUpperBoundAppo = Configuration.getDouble(prefix + "." + PAR_RELINKING_UPPER_BOUND, DEFAULT_RELINKING_UPPER_BOUND);\r
- if (relinkingLowerBoundAppo > relinkingUpperBoundAppo) {\r
- relinkingLowerBound = DEFAULT_RELINKING_LOWER_BOUND;\r
- relinkingUpperBound = DEFAULT_RELINKING_UPPER_BOUND;\r
- } else {\r
- relinkingLowerBound = relinkingLowerBoundAppo;\r
- relinkingUpperBound = relinkingUpperBoundAppo;\r
- }\r
-\r
- keepAliveMap = new HashMap<Node, Integer>();\r
-\r
- printConfig();\r
- }\r
-\r
- private void printConfig() {\r
-\r
- if (firstPrintConfig) {\r
- firstPrintConfig = false;\r
- System.out.println(SymphonyNetworkManager.class.getSimpleName() + " Configuration:");\r
- System.out.println("- Attempts per LongRangeLinks: " + attempts);\r
- System.out.println("- Number of Timeout before a node is considered OFFLINE (through Keep-alive):" + nTimeout);\r
- System.out.println("- Relinking: " + (relinkingProtocolActivated ? "ON" : "OFF"));\r
- System.out.println("- Relinking Range: [" + relinkingLowerBound + ", " + relinkingUpperBound + "]");\r
- System.out.println("-------------------------------\n");\r
- }\r
- }\r
-\r
- public void join(final Node node, final Node bootstrapNode) throws RoutingException {\r
- final SymphonyProtocol bootstrapSymphony = (SymphonyProtocol) bootstrapNode.getProtocol(symphonyID);\r
- SymphonyProtocol symphony = (SymphonyProtocol) node.getProtocol(symphonyID);\r
-\r
- /*\r
- * Search (through the bootstrap node) and contact the Manager Node of myself such a way to\r
- * be able to insert myself into the ring and create the short links\r
- *\r
- */\r
- bootstrapSymphony.route(bootstrapNode, symphony.getIdentifier(), new Handler() {\r
-\r
- public void handle(SymphonyProtocol src, Tuple<Node, Double> tuple) {\r
- if (tuple == null) {\r
- Logger.getLogger(SymphonyNetworkManager.class.getName()).log(Level.SEVERE, "FAIL ROUTE JOIN");\r
- node.setFailState(Fallible.DEAD);\r
- return;\r
- }\r
-\r
- Node managerNode = tuple.x;\r
-\r
- Transport transport = (Transport) node.getProtocol(transportID);\r
- Message msg = new Message(node, node, MessageType.JOIN);\r
- transport.send(node, managerNode, msg, pid);\r
- }\r
- });\r
-\r
- // The Long Range Links are added after that i joined the ring (before i can't because i haven't got the nodes to do the routing)\r
- }\r
-\r
- /**\r
- * Conservative Re-Linking (i reuse the ones already created: not all fresh)\r
- *\r
- * @param node\r
- */\r
- public void updateLongRangeLinks(Node node) {\r
- SymphonyProtocol symphony = (SymphonyProtocol) node.getProtocol(symphonyID);\r
- Transport transport = (Transport) node.getProtocol(transportID);\r
-\r
- // if too much links i delete the farest ones\r
- while (symphony.longRangeLinksOutgoing.size() > k) {\r
- Node distantNode = Collections.max(symphony.longRangeLinksOutgoing, new SymphonyNodeComparator(symphonyID, node));\r
- symphony.longRangeLinksOutgoing.remove(distantNode);\r
-\r
- // Communicate to the outgoing node that it ins't anymore one of my long range links\r
- Message disconnectMsg = new Message(null, node, MessageType.DISCONNECT_LONG_RANGE_LINK);\r
- transport.send(node, distantNode, disconnectMsg, pid);\r
- }\r
-\r
- // I can search Long Range Links only if i'm into the ring and i'm able to do routing\r
- if (symphony.isBootstrapped()) {\r
- // if only few i try again, untill attempts times, to add new ones\r
- int difference = k - symphony.longRangeLinksOutgoing.size();\r
- currentAttempts = attempts;\r
- for (int i = 0; i < difference; i++) {\r
- sendLongRangeLinkRequest(symphony, node);\r
- }\r
- }\r
- }\r
- private static final int MAX_ANTILOOP_COUNT_MANAGER_MYSELF = 5;\r
- private int antiLoopManagerMySelf = 0;\r
-\r
- private void sendLongRangeLinkRequest(final SymphonyProtocol symphony, final Node node) {\r
- boolean routingOk;\r
- do {\r
- double distance = Math.exp((Math.log(n) / Math.log(2)) * (CommonState.r.nextDouble() - 1.0)); // Harmonic Distribution\r
- double targetIdentifier = (symphony.getIdentifier() + distance) % 1;\r
- try {\r
-\r
- symphony.route(node, targetIdentifier, new Handler() {\r
-\r
- public void handle(SymphonyProtocol src, Tuple<Node, Double> tuple) {\r
-\r
- if (tuple == null) {\r
- Logger.getLogger(SymphonyNetworkManager.class.getName()).log(Level.SEVERE, "FAIL ROUTE SENDLONGRANGELINKREQUEST");\r
- return;\r
- }\r
-\r
- Collection<Node> allShortLinks = new LinkedList<Node>();\r
- for (Tuple<Node, BootstrapStatus> shortTuple : symphony.leftShortRangeLinks) {\r
- allShortLinks.add(shortTuple.x);\r
- }\r
- for (Tuple<Node, BootstrapStatus> shortTuple : symphony.rightShortRangeLinks) {\r
- allShortLinks.add(shortTuple.x);\r
- }\r
-\r
- /*\r
- *\r
- * I'm myself one of my short links, special case... i try again without\r
- * reduce the attempts for a maximum of MAX_ANTILOOP_COUNT_MANAGER_MYSELF\r
- * times after that i start again to reduce the attempts\r
- */\r
- if (tuple.x.equals(node) || allShortLinks.contains(tuple.x)) {\r
-\r
- if (antiLoopManagerMySelf < MAX_ANTILOOP_COUNT_MANAGER_MYSELF) {\r
-\r
- antiLoopManagerMySelf++;\r
- sendLongRangeLinkRequest(symphony, node);\r
- } else {\r
- antiLoopManagerMySelf = 0;\r
- currentAttempts--;\r
- }\r
- } else {\r
-\r
- boolean alreadyAdded = symphony.longRangeLinksOutgoing.contains(tuple.x);\r
- /*\r
- *\r
- * OPINABLE: DESCREASE ATTEMPTS ONLY FOR REJECT? If yes i have to manage\r
- * the possible loop (nodi exhaurited so already all added)\r
- */\r
- if (alreadyAdded && currentAttempts > 0) {\r
- currentAttempts--;\r
- sendLongRangeLinkRequest(symphony, node);\r
- } else if (!alreadyAdded) {\r
- Message msg = new Message(null, node, MessageType.REQUEST_LONG_RANGE_LINK);\r
- Transport transport = (Transport) node.getProtocol(transportID);\r
- transport.send(node, tuple.x, msg, pid);\r
- }\r
- }\r
- }\r
- });\r
- routingOk = true;\r
- } catch (RoutingException ex) {\r
- routingOk = false;\r
- }\r
- } while (!routingOk);\r
- }\r
-\r
- public void leave(Node node) {\r
- SymphonyProtocol symphony = (SymphonyProtocol) node.getProtocol(symphonyID);\r
-\r
- if (symphony.loggedIntoNetwork != BootstrapStatus.OFFLINE) {\r
- Transport transport = (Transport) node.getProtocol(transportID);\r
-\r
- symphony.loggedIntoNetwork = BootstrapStatus.OFFLINE;\r
-\r
- // Communicate that i'm leaving to the outgoing (that i point to) nodes\r
- for (Node outgoingNode : symphony.longRangeLinksOutgoing) {\r
- Message disconnectMsg = new Message(null, node, MessageType.DISCONNECT_LONG_RANGE_LINK);\r
- transport.send(node, outgoingNode, disconnectMsg, pid);\r
- }\r
-\r
- // Communicate that i'm leaving to the incoming (that they point to me) nodes\r
- for (Node incomingNode : symphony.longRangeLinksIncoming) {\r
- Message unavailableMsg = new Message(null, node, MessageType.UNAVAILABLE_LONG_RANGE_LINK);\r
- transport.send(node, incomingNode, unavailableMsg, pid);\r
- }\r
-\r
- // Communicate to my neighbours (short range links) that i'm leaving and i send to them the near neighbours\r
- for (Tuple<Node, BootstrapStatus> leftTuple : symphony.leftShortRangeLinks) {\r
- Message leaveMsg = new Message(symphony.rightShortRangeLinks.clone(), node, MessageType.LEAVE);\r
- transport.send(node, leftTuple.x, leaveMsg, pid);\r
- }\r
-\r
- for (Tuple<Node, BootstrapStatus> rightTuple : symphony.rightShortRangeLinks) {\r
- Message leaveMsg = new Message(symphony.leftShortRangeLinks.clone(), node, MessageType.LEAVE);\r
- transport.send(node, rightTuple.x, leaveMsg, pid);\r
- }\r
-\r
- node.setFailState(Fallible.DEAD);\r
- }\r
- }\r
-\r
- public void processEvent(Node node, int pid, Object event) {\r
-\r
- Message msg = (Message) event;\r
-\r
- SymphonyProtocol symphony = (SymphonyProtocol) node.getProtocol(symphonyID);\r
- Transport transport = (Transport) node.getProtocol(transportID);\r
-\r
- Collection<Tuple<Node, BootstrapStatus>> collection = null;\r
- switch (msg.getType()) {\r
- case JOIN:\r
- // I send my current neighbours to the entering node\r
- collection = (Collection<Tuple<Node, BootstrapStatus>>) symphony.leftShortRangeLinks.clone();\r
- collection.addAll((Collection<Tuple<Node, BootstrapStatus>>) symphony.rightShortRangeLinks.clone());\r
- Message responseMsg = new Message(collection, node, MessageType.JOIN_RESPONSE);\r
- transport.send(node, msg.getSourceNode(), responseMsg, pid);\r
-\r
- /*\r
- * Update my neighbours list, adding the new one (for sure it is entering in the\r
- * left side)\r
- *\r
- * Put to "ONLINE_AND_ALL_NEIGHBOURS_OFFLINE" because maybe the bootstrap phase is\r
- * not terminated yet (ashyncronous communication)\r
- */\r
- symphony.leftShortRangeLinks.add(new Tuple<Node, BootstrapStatus>(msg.getSourceNode(), BootstrapStatus.ONLINE_AND_ALL_NEIGHBOURS_OFFLINE));\r
-\r
-\r
- fixNeighbours(node, symphony.leftShortRangeLinks);\r
- break;\r
- case JOIN_RESPONSE:\r
-\r
- Collection<Tuple<Node, BootstrapStatus>> tupleCollection = (Collection<Tuple<Node, BootstrapStatus>>) msg.getBody();\r
-\r
- /*\r
- *\r
- * My manager is a right neighbour. The manager is already inside the ring, boostrap\r
- * obliviously ok\r
- */\r
- symphony.rightShortRangeLinks.add(new Tuple<Node, BootstrapStatus>(msg.getSourceNode(), BootstrapStatus.ONLINE));\r
-\r
- // Set my neighbours in the correct position\r
- for (Tuple<Node, BootstrapStatus> tuple : tupleCollection) {\r
- if (SymphonyProtocol.isLeftNeighbour(node, tuple.x)) {\r
- symphony.leftShortRangeLinks.add(tuple);\r
- } else {\r
- symphony.rightShortRangeLinks.add(tuple);\r
- }\r
- }\r
-\r
- fixNeighbours(node, symphony.leftShortRangeLinks);\r
- fixNeighbours(node, symphony.rightShortRangeLinks);\r
-\r
- // Update bootstrap status\r
- checkBootstrapStatus(node);\r
-\r
- // I send the refresh command such a way to exchange the views\r
- refreshNeighbours(node);\r
-\r
- // Update Long Range Links, because it's at the beginning is the same as adding k\r
- updateLongRangeLinks(node);\r
- break;\r
- case UPDATE_NEIGHBOURS:\r
-\r
- Collection<Tuple<Node, BootstrapStatus>> collectionCloned = ((Collection<Tuple<Node, BootstrapStatus>>) symphony.leftShortRangeLinks.clone());\r
- collectionCloned.addAll(((Collection<Tuple<Node, BootstrapStatus>>) symphony.rightShortRangeLinks.clone()));\r
-\r
- // Send my neighbours such a way it can also update itself\r
- Message responseUpdateMsg = new Message(collectionCloned, node, MessageType.UPDATE_NEIGHBOURS_RESPONSE);\r
- transport.send(node, msg.getSourceNode(), responseUpdateMsg, pid);\r
-\r
- // Update my view with the new node\r
- Tuple<Node, BootstrapStatus> neighbourTuple = new Tuple<Node, BootstrapStatus>(msg.getSourceNode(), (BootstrapStatus) msg.getBody());\r
- if (SymphonyProtocol.isLeftNeighbour(node, msg.getSourceNode())) {\r
- collection = symphony.leftShortRangeLinks;\r
- } else {\r
- collection = symphony.rightShortRangeLinks;\r
- }\r
- collection.add(neighbourTuple);\r
-\r
- fixNeighbours(node, collection);\r
- fixLookAheadMap(node);\r
- break;\r
- case UPDATE_NEIGHBOURS_RESPONSE:\r
-\r
- Collection<Tuple<Node, BootstrapStatus>> responseCollection = (Collection<Tuple<Node, BootstrapStatus>>) msg.getBody();\r
-\r
- for (Tuple<Node, BootstrapStatus> neighbourResponseTuple : responseCollection) {\r
- if (SymphonyProtocol.isLeftNeighbour(node, neighbourResponseTuple.x)) {\r
- collection = symphony.leftShortRangeLinks;\r
- } else {\r
- collection = symphony.rightShortRangeLinks;\r
- }\r
- collection.add(neighbourResponseTuple);\r
- }\r
-\r
- // Fix the neighbours number to the maximum allow and maybe remove myself from the list\r
- fixNeighbours(node, symphony.leftShortRangeLinks);\r
- fixNeighbours(node, symphony.rightShortRangeLinks);\r
- fixLookAheadMap(node);\r
- break;\r
- case UPDATE_STATUS:\r
- case UPDATE_STATUS_RESPONSE:\r
-\r
- Node updNode = msg.getSourceNode();\r
- BootstrapStatus updStatus = (BootstrapStatus) msg.getBody();\r
-\r
- // I search the neighbour and i update its status\r
- boolean founded = false;\r
-\r
- // Try to see if it is on the left\r
- for (Tuple<Node, BootstrapStatus> leftTuple : symphony.leftShortRangeLinks) {\r
- if (leftTuple.x.equals(updNode)) {\r
- symphony.leftShortRangeLinks.remove(leftTuple);\r
- symphony.leftShortRangeLinks.add(new Tuple<Node, BootstrapStatus>(updNode, updStatus));\r
-\r
- founded = true;\r
- break;\r
- }\r
- }\r
-\r
- // If it isn't on the left i try with the neighbours on the right\r
- if (!founded) {\r
- for (Tuple<Node, BootstrapStatus> rightTuple : symphony.rightShortRangeLinks) {\r
- if (rightTuple.x.equals(updNode)) {\r
- symphony.rightShortRangeLinks.remove(rightTuple);\r
- symphony.rightShortRangeLinks.add(new Tuple<Node, BootstrapStatus>(updNode, updStatus));\r
-\r
- break;\r
- }\r
- }\r
-\r
- fixNeighbours(node, symphony.rightShortRangeLinks);\r
- } else {\r
- fixNeighbours(node, symphony.leftShortRangeLinks);\r
- }\r
-\r
- checkBootstrapStatusAndAlert(node);\r
-\r
- if (msg.getType() == MessageType.UPDATE_STATUS) {\r
- Message responseUpdStatus = new Message(symphony.loggedIntoNetwork, node, MessageType.UPDATE_STATUS_RESPONSE);\r
- transport.send(node, updNode, responseUpdStatus, pid);\r
- }\r
-\r
- break;\r
- case REQUEST_LONG_RANGE_LINK:\r
- MessageType responseType = MessageType.REJECT_LONG_RANGE_LINK;\r
- if (symphony.longRangeLinksIncoming.size() < (2 * k)) {\r
- boolean added = symphony.longRangeLinksIncoming.add(msg.getSourceNode());\r
- if (added) {\r
- responseType = MessageType.ACCEPTED_LONG_RANGE_LINK;\r
- }\r
- }\r
- Message responseLongLinkMsg = new Message(null, node, responseType);\r
- transport.send(node, msg.getSourceNode(), responseLongLinkMsg, pid);\r
- break;\r
- case ACCEPTED_LONG_RANGE_LINK:\r
- nLink = n;\r
- symphony.longRangeLinksOutgoing.add(msg.getSourceNode());\r
- break;\r
- case REJECT_LONG_RANGE_LINK:\r
- if (currentAttempts > 0) {\r
- currentAttempts--;\r
- sendLongRangeLinkRequest(symphony, node);\r
- }\r
- break;\r
- case DISCONNECT_LONG_RANGE_LINK:\r
- symphony.longRangeLinksIncoming.remove(msg.getSourceNode());\r
- symphony.lookAheadMap.put(msg.getSourceNode(), null);\r
- break;\r
- case UNAVAILABLE_LONG_RANGE_LINK:\r
- symphony.longRangeLinksOutgoing.remove(msg.getSourceNode());\r
- symphony.lookAheadMap.put(msg.getSourceNode(), null);\r
- break;\r
- case LEAVE:\r
- Tuple<Node, BootstrapStatus> foundedTuple = null;\r
-\r
- // Verify if the node that is leaving is a left neighbour\r
- for (Tuple<Node, BootstrapStatus> leftTuple : symphony.leftShortRangeLinks) {\r
- if (leftTuple.x.equals(msg.getSourceNode())) {\r
- collection = symphony.leftShortRangeLinks;\r
- foundedTuple = leftTuple;\r
- break;\r
- }\r
- }\r
-\r
- // Verify if the node that is leaving is a right neighbour\r
- if (collection == null) {\r
- for (Tuple<Node, BootstrapStatus> rightTuple : symphony.rightShortRangeLinks) {\r
- if (rightTuple.x.equals(msg.getSourceNode())) {\r
- collection = symphony.rightShortRangeLinks;\r
- foundedTuple = rightTuple;\r
- break;\r
- }\r
- }\r
- }\r
-\r
- // if i've found the neighbour i remove it and i add to myself its neighbours\r
- if (collection != null) {\r
- collection.addAll((Collection<Tuple<Node, BootstrapStatus>>) msg.getBody());\r
- collection.remove(foundedTuple);\r
- fixNeighbours(node, collection);\r
-\r
- // Update status and ready to send an alert in case i'm out of the ring\r
- checkBootstrapStatusAndAlert(node);\r
- }\r
- break;\r
- case KEEP_ALIVE:\r
- Set<Double>[] lookAheadSetArray = new LinkedHashSet[2];\r
-\r
- /*\r
- * Check if the contacting node is doing lookAhead and in case of affirmative answer\r
- * i provide to it the long range link identifiers (according to my routing mode)\r
- */\r
- if ((Boolean) msg.getBody()) {\r
- int i = 0;\r
- Iterable[] iterableArray;\r
- if (symphony.bidirectionalRouting) {\r
- iterableArray = new Iterable[]{symphony.longRangeLinksOutgoing, symphony.longRangeLinksIncoming};\r
- } else {\r
- iterableArray = new Iterable[]{symphony.longRangeLinksOutgoing};\r
- }\r
-\r
- for (Iterable<Node> iterable : iterableArray) {\r
- lookAheadSetArray[i] = new LinkedHashSet<Double>();\r
- Set<Double> lookAheadSet = lookAheadSetArray[i];\r
- Iterator<Node> it = iterable.iterator();\r
- while (it.hasNext()) {\r
- Node longLinkNode = it.next();\r
- lookAheadSet.add(((SymphonyProtocol) longLinkNode.getProtocol(symphonyID)).getIdentifier());\r
- }\r
- i++;\r
- }\r
- }\r
-\r
- transport.send(node, msg.getSourceNode(), new Message(lookAheadSetArray, node, MessageType.KEEP_ALIVE_RESPONSE), pid);\r
- break;\r
- case KEEP_ALIVE_RESPONSE:\r
- // Reset the counter to 0\r
- keepAliveMap.put(msg.getSourceNode(), 0);\r
-\r
- if (symphony.lookAhead) {\r
- symphony.lookAheadMap.put(msg.getSourceNode(), (Set<Double>[]) msg.getBody());\r
- }\r
-\r
- break;\r
- }\r
- }\r
-\r
- /**\r
- *\r
- * Update the status and communicate immediately to the neighbours if the node is gone out from\r
- * the ring (and before it was inside)\r
- *\r
- * @param node\r
- */\r
- private void checkBootstrapStatusAndAlert(Node node) {\r
- SymphonyProtocol symphony = (SymphonyProtocol) node.getProtocol(symphonyID);\r
- BootstrapStatus beforeStatus = symphony.loggedIntoNetwork;\r
-\r
- checkBootstrapStatus(node);\r
-\r
- // Instead of waiting that the update happens periodically i do it now because i'm out of the ring and before i wasn't\r
- if (symphony.loggedIntoNetwork != beforeStatus && !symphony.isBootstrapped()) {\r
- updateBootstrapStatusNeighbours(node, true);\r
- }\r
- }\r
-\r
- private void fixNeighbours(Node node, Collection<Tuple<Node, BootstrapStatus>> neighbours) {\r
-\r
- SymphonyProtocol symphony = (SymphonyProtocol) node.getProtocol(symphonyID);\r
-\r
- // Remove duplicates, remove that ones that are in an obsolete status\r
- Collection<Tuple<Node, BootstrapStatus>> removedNeighbours = new LinkedHashSet<Tuple<Node, BootstrapStatus>>();\r
- for (Tuple<Node, BootstrapStatus> tuple : neighbours) {\r
-\r
- // Remove myself from the neighbours list\r
- if (tuple.x.equals(node)) {\r
- removedNeighbours.add(tuple);\r
- continue;\r
- }\r
-\r
- EnumSet<BootstrapStatus> status = EnumSet.allOf(BootstrapStatus.class);\r
- status.remove(tuple.y);\r
-\r
- for (BootstrapStatus opposite : status) {\r
- Tuple<Node, BootstrapStatus> oppositeNeighbour = new Tuple<Node, BootstrapStatus>(tuple.x, opposite);\r
- if (neighbours.contains(oppositeNeighbour)) {\r
- if (tuple.y != BootstrapStatus.ONLINE) {\r
- removedNeighbours.add(new Tuple<Node, BootstrapStatus>(tuple.x, BootstrapStatus.OFFLINE));\r
- if (opposite == BootstrapStatus.ONLINE) {\r
- removedNeighbours.add(new Tuple<Node, BootstrapStatus>(tuple.x, BootstrapStatus.ONLINE_AND_ALL_NEIGHBOURS_OFFLINE));\r
- }\r
- }\r
- }\r
- }\r
- }\r
- neighbours.removeAll(removedNeighbours);\r
-\r
- /*\r
- *\r
- * I count the neighbours that are in the ONLINE status but before i remove the ones that\r
- * are gone in timeout during the keep-alive procedure because can be someone that is old\r
- * but not remove from the exchanging views (UPDATE_NEIGHBOURS) procedure and are not\r
- * effectively online. To do anyway the possibility to the node to join again i decrease its\r
- * timeout value. This only if the node is ONLINE and so i'm really interested that it is ok\r
- * for the routing.\r
- *\r
- */\r
- int onlineNeighbours = 0;\r
- for (Tuple<Node, BootstrapStatus> tuple : neighbours) {\r
-\r
- Integer value = keepAliveMap.get(tuple.x);\r
- if (value != null && value >= nTimeout && tuple.y == BootstrapStatus.ONLINE) {\r
- keepAliveMap.put(tuple.x, value - 1);\r
- removedNeighbours.add(tuple);\r
- } else {\r
-\r
- if (tuple.y == BootstrapStatus.ONLINE) {\r
- onlineNeighbours++;\r
- }\r
- }\r
- }\r
- neighbours.removeAll(removedNeighbours);\r
-\r
- // Fix the neighbours number to the maximum allowed\r
- SymphonyNodeComparator comparator = new SymphonyNodeComparator(symphonyID, node);\r
- AdapterSymphonyNodeComparator adapterComparator = new AdapterSymphonyNodeComparator(comparator);\r
- while (neighbours.size() > symphony.numberShortRangeLinksPerSide) {\r
- Tuple<Node, BootstrapStatus> distantTuple = Collections.max(neighbours, adapterComparator);\r
-\r
- // Mantain the link with the ring\r
- if (distantTuple.y == BootstrapStatus.ONLINE) {\r
- if (onlineNeighbours > 1) {\r
- neighbours.remove(distantTuple);\r
- onlineNeighbours--;\r
- } else {\r
- /*\r
- * If will be only one neighbour that is online i save it and i'm going to\r
- * eliminate another one (for sure it'll be not online)\r
- *\r
- */\r
- Tuple<Node, BootstrapStatus> backupOnlineNeighbour = distantTuple;\r
- neighbours.remove(backupOnlineNeighbour);\r
- distantTuple = Collections.max(neighbours, adapterComparator);\r
- neighbours.add(backupOnlineNeighbour);\r
- neighbours.remove(distantTuple);\r
- }\r
-\r
- } else {\r
- neighbours.remove(distantTuple);\r
- }\r
- }\r
- }\r
-\r
- @Override\r
- public Object clone() {\r
- SymphonyNetworkManager dolly = new SymphonyNetworkManager(prefix);\r
- return dolly;\r
- }\r
-\r
- public void nextCycle(Node node, int protocolID) {\r
-\r
- if (node.isUp()) {\r
-\r
- // Update the estimated network size\r
- updateN(node);\r
-\r
- // Update the estimated K\r
- updateK(node);\r
-\r
- // Update the bootstrap status of my neighbours that were joining the ring\r
- updateBootstrapStatusNeighbours(node, false);\r
-\r
- // Refresh the neighbours views\r
- refreshNeighbours(node);\r
-\r
- // I send and check the connection status of the neighbours\r
- keepAlive(node);\r
-\r
- // Update the bootstrap status\r
- checkBootstrapStatus(node);\r
-\r
- // If it's active i check the Relinking criteria\r
- if (relinkingProtocolActivated) {\r
- reLinkingProtocol(node);\r
- }\r
-\r
- // Update the long range links (conservative)\r
- updateLongRangeLinks(node);\r
- }\r
- }\r
-\r
- /**\r
- *\r
- * @param allNeighbours true, communicate/receive the status update from all the neighbours.\r
- * false, communicate/receive the status update only from the neighbours that are NOT ONLINE\r
- *\r
- */\r
- private void updateBootstrapStatusNeighbours(Node node, boolean allNeighbours) {\r
- SymphonyProtocol symphony = (SymphonyProtocol) node.getProtocol(symphonyID);\r
- Transport transport = (Transport) node.getProtocol(transportID);\r
-\r
- Collection<Tuple<Node, BootstrapStatus>> collection = new LinkedHashSet<Tuple<Node, BootstrapStatus>>();\r
- collection.addAll(symphony.leftShortRangeLinks);\r
- collection.addAll(symphony.rightShortRangeLinks);\r
-\r
- for (Tuple<Node, BootstrapStatus> neighbourTuple : collection) {\r
- if (allNeighbours || neighbourTuple.y != BootstrapStatus.ONLINE) {\r
- Message msg = new Message(symphony.loggedIntoNetwork, node, MessageType.UPDATE_STATUS);\r
- transport.send(node, neighbourTuple.x, msg, pid);\r
- }\r
- }\r
- }\r
-\r
- private void updateN(Node node) {\r
- NetworkSizeEstimatorProtocolInterface networkEstimator = (NetworkSizeEstimatorProtocolInterface) node.getProtocol(networkEstimatorID);\r
- n = networkEstimator.getNetworkSize(node);\r
- if (n <= 0) {\r
- n = DEFAULT_N;\r
- }\r
- }\r
-\r
- /**\r
- * Update the K value with the current expectation of the network size\r
- */\r
- private void updateK(Node node) {\r
-\r
- SymphonyProtocol symphony = (SymphonyProtocol) node.getProtocol(symphonyID);\r
- if (!symphony.fixedLongRangeLinks) {\r
- k = (int) Math.ceil(Math.log(n) / Math.log(2));\r
-\r
- if (k <= 0) {\r
- k = DEFAULT_K;\r
- }\r
- } else {\r
- k = symphony.numberFixedLongRangeLinks;\r
- }\r
- }\r
-\r
- private void refreshNeighbours(Node node) {\r
- SymphonyProtocol symphony = (SymphonyProtocol) node.getProtocol(symphonyID);\r
- Transport transport = (Transport) node.getProtocol(transportID);\r
-\r
- for (Tuple<Node, BootstrapStatus> leftTuple : symphony.leftShortRangeLinks) {\r
- Node leftNode = leftTuple.x;\r
- Message updateNeighbourMsg = new Message(symphony.loggedIntoNetwork, node, MessageType.UPDATE_NEIGHBOURS);\r
- transport.send(node, leftNode, updateNeighbourMsg, pid);\r
- }\r
-\r
- for (Tuple<Node, BootstrapStatus> rightTuple : symphony.rightShortRangeLinks) {\r
- Node rightNode = rightTuple.x;\r
- Message updateNeighbourMsg = new Message(symphony.loggedIntoNetwork, node, MessageType.UPDATE_NEIGHBOURS);\r
- transport.send(node, rightNode, updateNeighbourMsg, pid);\r
- }\r
- }\r
-\r
- /**\r
- * Method to update the (connection) status of the node. Perform the update to the "up" so:\r
- * OFFLINE -> ONLINE_AND_ALL_NEIGHBOURS_OFFLINE -> ONLINE\r
- *\r
- * and to the "down" only: ONLINE -> ONLINE_AND_ALL_NEIGHBOURS_OFFLINE\r
- *\r
- * @param node\r
- */\r
- private void checkBootstrapStatus(Node node) {\r
- SymphonyProtocol symphony = (SymphonyProtocol) node.getProtocol(symphonyID);\r
-\r
- if (symphony.loggedIntoNetwork != BootstrapStatus.OFFLINE) {\r
-\r
- symphony.loggedIntoNetwork = BootstrapStatus.ONLINE_AND_ALL_NEIGHBOURS_OFFLINE;\r
-\r
- // Check if i'm inside the ring and i'm able to do routing\r
- if (!symphony.leftShortRangeLinks.isEmpty() && !symphony.rightShortRangeLinks.isEmpty()) {\r
-\r
- boolean leftOk = false;\r
- for (Tuple<Node, BootstrapStatus> leftTuple : symphony.leftShortRangeLinks) {\r
- if (leftTuple.y == BootstrapStatus.ONLINE) {\r
- leftOk = true;\r
- break;\r
- }\r
- }\r
-\r
- if (leftOk) {\r
- for (Tuple<Node, BootstrapStatus> rightTuple : symphony.rightShortRangeLinks) {\r
- if (rightTuple.y == BootstrapStatus.ONLINE) {\r
- symphony.loggedIntoNetwork = BootstrapStatus.ONLINE;\r
- break;\r
- }\r
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
- /**\r
- * Remove the possible wrong entries from the lookAhead table\r
- */\r
- private void fixLookAheadMap(Node node) {\r
- SymphonyProtocol symphony = (SymphonyProtocol) node.getProtocol(symphonyID);\r
- for (Tuple<Node, BootstrapStatus> tuple : symphony.leftShortRangeLinks) {\r
- symphony.lookAheadMap.put(tuple.x, null);\r
- }\r
- for (Tuple<Node, BootstrapStatus> tuple : symphony.rightShortRangeLinks) {\r
- symphony.lookAheadMap.put(tuple.x, null);\r
- }\r
- }\r
-\r
- /**\r
- * Sent keep-alive messages to verify if the links still online\r
- *\r
- * if enable the lookAhead mode i require the neighbours list from my neighbours (1-lookAhead).\r
- *\r
- * Note: I don't reuse the UPDATE_STATUS messages because i want to mantain separate the\r
- * semantic and have more clear source code\r
- */\r
- private void keepAlive(Node node) {\r
-\r
- SymphonyProtocol symphony = (SymphonyProtocol) node.getProtocol(symphonyID);\r
- Transport transport = (Transport) node.getProtocol(transportID);\r
-\r
- // Send and check for the long range links (both incoming and outgoing)\r
- for (Iterable<Node> iterable : new Iterable[]{symphony.longRangeLinksOutgoing, symphony.longRangeLinksIncoming}) {\r
- Iterator<Node> longLinksIterator = iterable.iterator();\r
- while (longLinksIterator.hasNext()) {\r
- Node longLinkNode = longLinksIterator.next();\r
- Integer value = keepAliveMap.get(longLinkNode);\r
- if (value == null) {\r
- value = 0;\r
- }\r
-\r
- /*\r
- * Verify if i reached the sufficient time of sending and not receiving an answer\r
- * and so i can consider that node as disconnected\r
- */\r
- if (value >= nTimeout) {\r
- symphony.lookAheadMap.put(longLinkNode, null); // Do it anyway if it's enabled the lookAhead or not\r
- longLinksIterator.remove();\r
- } else {\r
- keepAliveMap.put(longLinkNode, value + 1);\r
-\r
- Message keepAliveMsg = new Message(symphony.lookAhead, node, MessageType.KEEP_ALIVE);\r
- transport.send(node, longLinkNode, keepAliveMsg, pid);\r
- }\r
- }\r
- }\r
-\r
- // Send and check for the short links\r
- for (Iterable<Tuple<Node, BootstrapStatus>> iterable : new Iterable[]{symphony.rightShortRangeLinks, symphony.leftShortRangeLinks}) {\r
- Iterator<Tuple<Node, BootstrapStatus>> shortLinksIterator = iterable.iterator();\r
- while (shortLinksIterator.hasNext()) {\r
- Node shortLinkNode = shortLinksIterator.next().x;\r
- Integer value = keepAliveMap.get(shortLinkNode);\r
- if (value == null) {\r
- value = 0;\r
- }\r
-\r
- // the same as above\r
- if (value >= nTimeout) {\r
- shortLinksIterator.remove();\r
- } else {\r
- keepAliveMap.put(shortLinkNode, value + 1);\r
-\r
- // LookAhead is not to be performed to the short links!\r
- Message keepAliveMsg = new Message(false, node, MessageType.KEEP_ALIVE);\r
- transport.send(node, shortLinkNode, keepAliveMsg, pid);\r
- }\r
- }\r
- }\r
- }\r
-\r
- /**\r
- * Implement the Re-Linking criteria of the Long Range Links. It does the complete refresh. The\r
- * repopulation is done through the 'updateLongRangeLinks' method.\r
- */\r
- private void reLinkingProtocol(Node node) {\r
- // I do the check only if i succeed at least one time to create a long range link\r
- if (nLink > 0) {\r
- double criterionValue = n / nLink;\r
-\r
- if (!(criterionValue >= relinkingLowerBound && criterionValue <= relinkingUpperBound)) {\r
-\r
- /*\r
- * Not explicitly precised in the paper: if i haven't created a new link i update\r
- * anyway nLink because can happen a special case that i will not be able to create\r
- * links because the reLinkingProtocol procedure is "faster".\r
- */\r
- nLink = n;\r
-\r
- SymphonyProtocol symphony = (SymphonyProtocol) node.getProtocol(symphonyID);\r
- Transport transport = (Transport) node.getProtocol(transportID);\r
-\r
- // Communicate to the all Outgoing Long Range Links that they aren't anymore\r
- for (Node longRangeLinkOutgoingNode : symphony.longRangeLinksOutgoing) {\r
- Message disconnectMsg = new Message(null, node, MessageType.DISCONNECT_LONG_RANGE_LINK);\r
- transport.send(node, longRangeLinkOutgoingNode, disconnectMsg, pid);\r
- }\r
-\r
- symphony.longRangeLinksOutgoing.clear();\r
- }\r
- }\r
- }\r
-\r
- public int getK() {\r
- return k;\r
- }\r
-\r
- public int getN() {\r
- return n;\r
- }\r
-}\r
+++ /dev/null
-package example.symphony;\r
-\r
-import java.util.Comparator;\r
-import java.util.logging.Level;\r
-import java.util.logging.Logger;\r
-import peersim.core.Node;\r
-\r
-/**\r
- * Comparator that measure the relative distance from a target node\r
- *\r
- * @author Andrea Esposito <and1989@gmail.com>\r
- */\r
-public class SymphonyNodeComparator implements Comparator<Node> {\r
-\r
- private final int symphonyID;\r
- private double target;\r
-\r
- public SymphonyNodeComparator(int symphonyID) {\r
- this.symphonyID = symphonyID;\r
- }\r
-\r
- public SymphonyNodeComparator(int symphonyID, double target) {\r
- this(symphonyID);\r
- this.target = target;\r
- }\r
-\r
- public SymphonyNodeComparator(int symphonyID, Node targetNode) {\r
- this(symphonyID);\r
- SymphonyProtocol symphony = (SymphonyProtocol) targetNode.getProtocol(symphonyID);\r
- this.target = symphony.getIdentifier();\r
- }\r
-\r
- public int compare(Node o1, Node o2) {\r
-\r
- SymphonyProtocol symphony1 = (SymphonyProtocol) o1.getProtocol(symphonyID);\r
- SymphonyProtocol symphony2 = (SymphonyProtocol) o2.getProtocol(symphonyID);\r
-\r
- Double identifier1 = symphony1.getIdentifier();\r
- Double identifier2 = symphony2.getIdentifier();\r
-\r
- Double distance1 = Math.abs(target - identifier1) % 1;\r
- Double distance2 = Math.abs(target - identifier2) % 1;\r
-\r
- identifier1 = Math.min(1.0 - distance1, distance1);\r
- identifier2 = Math.min(1.0 - distance2, distance2);\r
-\r
- Logger.getLogger(SymphonyNodeComparator.class.getName()).log(Level.FINEST, "id1= " + symphony1.getIdentifier() + " target= " + target + " id2= " + symphony2.getIdentifier() + " res= " + identifier1.compareTo(identifier2));\r
-\r
- return identifier1.compareTo(identifier2);\r
- }\r
-}\r
+++ /dev/null
-package example.symphony;\r
-\r
-import java.util.logging.Level;\r
-import java.util.logging.Logger;\r
-import peersim.config.Configuration;\r
-import peersim.core.Network;\r
-import peersim.core.Node;\r
-import peersim.dynamics.NodeInitializer;\r
-\r
-/**\r
- *\r
- * @author Andrea Esposito <and1989@gmail.com>\r
- */\r
-public class SymphonyNodeInizializer implements NodeInitializer {\r
-\r
- private static final String PAR_NETMANAGER = "symphonynetworkmanager";\r
- private static final String PAR_SYMPHONY = "symphony";\r
- private static final String PAR_BOOTNODE = "bootstrapnode";\r
- private final int networkManagerID;\r
- private final int symphonyID;\r
- private final int indexBootstrapNode;\r
-\r
- public SymphonyNodeInizializer(String prefix) {\r
-\r
- networkManagerID = Configuration.getPid(prefix + "." + PAR_NETMANAGER);\r
- indexBootstrapNode = Configuration.getInt(prefix + "." + PAR_BOOTNODE, 0);\r
- symphonyID = Configuration.getPid(prefix + "." + PAR_SYMPHONY);\r
- }\r
-\r
- @Override\r
- public void initialize(Node node) {\r
- int indexRealBootstrapNode = indexBootstrapNode;\r
- Node realBootstrapNode = Network.get(indexBootstrapNode);\r
- SymphonyNetworkManager symphonyNetworkManager = (SymphonyNetworkManager) node.getProtocol(networkManagerID);\r
- SymphonyProtocol symphony = (SymphonyProtocol) realBootstrapNode.getProtocol(symphonyID);\r
-\r
- boolean joinSent;\r
- do {\r
- try {\r
- while (!symphony.isBootstrapped() || !realBootstrapNode.isUp()) {\r
- indexRealBootstrapNode = (indexRealBootstrapNode + 1) % Network.size();\r
- realBootstrapNode = Network.get(indexRealBootstrapNode);\r
- symphony = (SymphonyProtocol) realBootstrapNode.getProtocol(symphonyID);\r
-\r
- if (indexRealBootstrapNode == indexBootstrapNode) {\r
- Logger.getLogger(SymphonyNodeInizializer.class.getName()).log(Level.WARNING, "No node ONLINE. Impossible to do the network bootstrap.");\r
- return;\r
- }\r
- }\r
-\r
- symphonyNetworkManager.join(node, realBootstrapNode);\r
- joinSent = true;\r
- } catch (RoutingException ex) {\r
- Logger.getLogger(SymphonyNodeInizializer.class.getName()).log(Level.SEVERE, "Join Issue");\r
- joinSent = false;\r
- }\r
- } while (!joinSent);\r
- }\r
-}\r
+++ /dev/null
-package example.symphony;\r
-\r
-import java.lang.ref.SoftReference;\r
-import java.util.*;\r
-import java.util.logging.Level;\r
-import java.util.logging.Logger;\r
-\r
-import example.symphony.Message.MessageType;\r
-import peersim.config.Configuration;\r
-import peersim.core.CommonState;\r
-import peersim.core.Node;\r
-import peersim.edsim.EDProtocol;\r
-import peersim.transport.Transport;\r
-\r
-/**\r
- *\r
- * @author Andrea Esposito <and1989@gmail.com>\r
- */\r
-public class SymphonyProtocol implements EDProtocol {\r
-\r
- private static final String PAR_SHORT_LINK = "shortlink";\r
- private static final String PAR_LONG_LINK = "longlink";\r
- private static final String PAR_TRANSP = "transport";\r
- private static final String PAR_ROUTING = "routing";\r
- private static final String PAR_LOOKAHEAD = "lookahead";\r
- private static Set<Double> allIdentifier = new HashSet<Double>();\r
- private final String prefix;\r
- private static int pid;\r
- private final int transportID;\r
- private final double identifier;\r
- public final int sequentialIdentifier;\r
- private static int sequentialCounter = 0;\r
- public final int numberShortRangeLinksPerSide;\r
- public final boolean bidirectionalRouting;\r
- public final boolean lookAhead;\r
- public final boolean fixedLongRangeLinks;\r
- public final int numberFixedLongRangeLinks;\r
- public LinkedHashSet<Node> longRangeLinksOutgoing;\r
- public LinkedHashSet<Node> longRangeLinksIncoming;\r
- public LinkedHashSet<Tuple<Node, BootstrapStatus>> rightShortRangeLinks;\r
- public LinkedHashSet<Tuple<Node, BootstrapStatus>> leftShortRangeLinks;\r
- /**\r
- * Array Contract: at position 0 -> OutgoingLongRangeLinks, 1 -> IncomingLongRangeLinks\r
- */\r
- public final LinkedHashMap<Node, Set<Double>[]> lookAheadMap;\r
- private HashMap<Double, Handler> mapHandler;\r
- /**\r
- * IDs Set to verify if there are cycles\r
- */\r
- private Set<Long> messageHistoryID;\r
- /**\r
- *\r
- * Tuple chronology that contains: <received message, the possible answer message>\r
- *\r
- * I use SoftReference as a trade off between memory usage and accurancy\r
- */\r
- private Set<SoftReference<Tuple<Message, Message>>> messageHistory;\r
- private static boolean firstPrintConfig = true;\r
-\r
- public enum BootstrapStatus {\r
-\r
- NEW, OFFLINE, ONLINE_AND_ALL_NEIGHBOURS_OFFLINE, ONLINE\r
- }\r
- public BootstrapStatus loggedIntoNetwork;\r
-\r
- public SymphonyProtocol(String prefix) {\r
-\r
- this.prefix = prefix;\r
- pid = Configuration.lookupPid(prefix.replaceAll("protocol.", ""));\r
- transportID = Configuration.getPid(prefix + "." + PAR_TRANSP);\r
- numberShortRangeLinksPerSide = Configuration.getInt(prefix + "." + PAR_SHORT_LINK, 2) / 2;\r
- bidirectionalRouting = !Configuration.getString(prefix + "." + PAR_ROUTING, "bidirectional").toLowerCase().equals("unidirectional");\r
- lookAhead = !Configuration.getString(prefix + "." + PAR_LOOKAHEAD, "on").toLowerCase().equals("off");\r
- numberFixedLongRangeLinks = Configuration.getInt(prefix + "." + PAR_LONG_LINK, -1);\r
- fixedLongRangeLinks = numberFixedLongRangeLinks >= 0;\r
-\r
- longRangeLinksOutgoing = new LinkedHashSet<Node>();\r
- longRangeLinksIncoming = new LinkedHashSet<Node>();\r
- rightShortRangeLinks = new LinkedHashSet<Tuple<Node, BootstrapStatus>>();\r
- leftShortRangeLinks = new LinkedHashSet<Tuple<Node, BootstrapStatus>>();\r
- lookAheadMap = new LinkedHashMap<Node, Set<Double>[]>();\r
-\r
- identifier = generateUniqueIdentifier();\r
- sequentialIdentifier = sequentialCounter++;\r
-\r
- mapHandler = new HashMap<Double, Handler>();\r
-\r
- messageHistoryID = new HashSet<Long>();\r
- messageHistory = new LinkedHashSet<SoftReference<Tuple<Message, Message>>>();\r
- loggedIntoNetwork = BootstrapStatus.NEW;\r
-\r
- printConfig();\r
- }\r
-\r
- private void printConfig() {\r
-\r
- if (firstPrintConfig) {\r
- firstPrintConfig = false;\r
- System.out.println(SymphonyProtocol.class.getSimpleName() + " Configuration:");\r
- System.out.println("- Number of short range links per side: " + numberShortRangeLinksPerSide);\r
- System.out.println("- Number of long range links: " + (fixedLongRangeLinks ? numberFixedLongRangeLinks : "log(n)"));\r
- System.out.println("- Routing mode: " + (bidirectionalRouting ? "Bidirectional" : "Unidirectional"));\r
- System.out.println("- LookAhead status: " + (lookAhead ? "ON" : "OFF"));\r
- System.out.println("-------------------------------\n");\r
- }\r
- }\r
-\r
- /**\r
- *\r
- * Method to identify the next node that has to be contacted. It's going to be used the mode\r
- * that is described into the configuration file\r
- */\r
- public Node getCandidateForRouting(double identifierToRoute) throws RoutingException {\r
- if (bidirectionalRouting) {\r
- return getCandidateForBidirectionalRoute(identifierToRoute);\r
- } else {\r
- return getCandidateForUnidirectionalRoute(identifierToRoute);\r
- }\r
- }\r
-\r
- /**\r
- *\r
- * Method to individuate the next node that as to be contacted through Unidirectional Routing\r
- * mode\r
- */\r
- public Node getCandidateForUnidirectionalRoute(double identifierToRoute) throws RoutingException {\r
-\r
- LinkedHashSet<Node> allLinks = new LinkedHashSet<Node>();\r
- Node manager = putShortRangeLinksIntoContainerForRouting(allLinks, identifierToRoute);\r
-\r
- if (manager != null) {\r
- return manager;\r
- }\r
-\r
- allLinks.addAll(longRangeLinksOutgoing);\r
-\r
- return findClosestNode(identifierToRoute, allLinks, true);\r
- }\r
-\r
- /**\r
- * Method to individuate the next node that as to be contacted through Bidirectional Routing\r
- * mode\r
- */\r
- public Node getCandidateForBidirectionalRoute(double identifierToRoute) throws RoutingException {\r
-\r
- LinkedHashSet<Node> allLinks = new LinkedHashSet<Node>();\r
- Node manager = putShortRangeLinksIntoContainerForRouting(allLinks, identifierToRoute);\r
-\r
- if (manager != null) {\r
- return manager;\r
- }\r
-\r
- allLinks.addAll(longRangeLinksOutgoing);\r
- allLinks.addAll(longRangeLinksIncoming);\r
-\r
- return findClosestNode(identifierToRoute, allLinks, false);\r
- }\r
-\r
- /**\r
- * @return Null if it is NOT found the manager. Node if it is found.\r
- */\r
- private Node putShortRangeLinksIntoContainerForRouting(Set<Node> container, double identifierToRoute) {\r
- for (Tuple<Node, BootstrapStatus> rightTuple : rightShortRangeLinks) {\r
- if (rightTuple.y == BootstrapStatus.ONLINE) {\r
- container.add(rightTuple.x);\r
- }\r
- }\r
-\r
- if (!container.isEmpty()) {\r
-\r
- // Special case: i verify if the neighbour at my right (ONLINE) is the manager\r
- SymphonyNodeComparator comparator = new SymphonyNodeComparator(pid, identifier);\r
- Node nearRightNeighbour = Collections.min(container, comparator);\r
- if (nearRightNeighbour != null) {\r
- SymphonyProtocol symphony = (SymphonyProtocol) nearRightNeighbour.getProtocol(pid);\r
- if (!isLeftNeighbour(identifier, identifierToRoute) && isLeftNeighbour(symphony.getIdentifier(), identifierToRoute)) {\r
- return nearRightNeighbour;\r
- }\r
- }\r
- }\r
-\r
- for (Tuple<Node, BootstrapStatus> leftTuple : leftShortRangeLinks) {\r
- if (leftTuple.y == BootstrapStatus.ONLINE) {\r
- container.add(leftTuple.x);\r
- }\r
- }\r
-\r
- return null;\r
- }\r
-\r
- /**\r
- *\r
- * Individuates effectively the next candidate for the routing. Checks if the lookahead is\r
- * activated and in case of affirmative answer it's going to use that information.\r
- *\r
- * @param identifierToRoute Identifier to reach\r
- * @param container Candidate Nodes Container\r
- * @param clockwise true, does unidirectional routing. false, does bidirectional routing.\r
- * @return The nearest node to reach identifierToRoute\r
- * @throws RoutingException Throw in case no candidate is found\r
- */\r
- public Node findClosestNode(final double identifierToRoute, final Iterable<Node> container, final boolean clockwise) throws RoutingException {\r
- Node ret = null;\r
- double min = Double.MAX_VALUE;\r
-\r
- for (Node node : container) {\r
- SymphonyProtocol symphonyNodeContainer = (SymphonyProtocol) node.getProtocol(pid);\r
- double realCandidateIdentifier = symphonyNodeContainer.getIdentifier();\r
-\r
- Set<Double> candidateIdentifierSet = new LinkedHashSet<Double>();\r
- candidateIdentifierSet.add(realCandidateIdentifier);\r
-\r
- boolean lookAheadClockwise = true;\r
-\r
- /*\r
- *\r
- * If lookahead is activated add all the reachable identifiers. No checks are performed\r
- * on the node type (short/long) because at maximum the map return null.\r
- */\r
- if (lookAhead) {\r
- Set<Double>[] lookAheadIdentifierSetArray = lookAheadMap.get(node);\r
-\r
- if (lookAheadIdentifierSetArray != null) {\r
- Set<Double> lookAheadIdentifierSet = lookAheadIdentifierSetArray[0];\r
-\r
- if (lookAheadIdentifierSet == null) {\r
- lookAheadIdentifierSet = new LinkedHashSet<Double>();\r
- }\r
-\r
- /*\r
- *\r
- * If bidirectional routing is going to be performed so i put into account also\r
- * the Incoming Long Range Links of the current neighbour\r
- */\r
- if (bidirectionalRouting && lookAheadIdentifierSetArray[1] != null) {\r
- lookAheadIdentifierSet.addAll(lookAheadIdentifierSetArray[1]);\r
- lookAheadClockwise = false;\r
- }\r
-\r
- if (!lookAheadIdentifierSet.isEmpty()) {\r
- candidateIdentifierSet.addAll(lookAheadIdentifierSet);\r
- }\r
- }\r
- }\r
-\r
- for (Double candidateIdentifier : candidateIdentifierSet) {\r
- // if it is a my neighbour i use my routing mode instead if it is a looAhead one i use its routing mode\r
- boolean currentClockwise = candidateIdentifier.equals(realCandidateIdentifier) ? clockwise : lookAheadClockwise;\r
-\r
- double distance = Math.abs(candidateIdentifier - identifierToRoute);\r
- distance = Math.min(distance, 1.0 - distance);\r
-\r
- // if clockwise i have to exclude the case: candidateIdentifier - indentifierToRoute - identifier\r
- if (currentClockwise) {\r
- if (isLeftNeighbour(candidateIdentifier, identifierToRoute)) {\r
-\r
- // Special case (0.9 - 0.1) the normal order is not more meanful to decide the side\r
- if (identifierToRoute >= candidateIdentifier) {\r
- distance = identifierToRoute - candidateIdentifier;\r
- } else {\r
- distance = (1.0 - candidateIdentifier) + identifierToRoute;\r
- }\r
- } else {\r
- distance = (1.0 - (candidateIdentifier - identifierToRoute)) % 1;\r
- }\r
- }\r
-\r
- /*\r
- *\r
- * Priority to the node that i'm directly connected and only after i use the\r
- * lookAhead information\r
- */\r
- if (min >= Math.abs(distance)\r
- && (candidateIdentifier.equals(realCandidateIdentifier)\r
- || ret == null\r
- || min > Math.abs(distance))) {\r
- ret = node;\r
- min = Math.abs(distance);\r
- }\r
- }\r
- }\r
-\r
- if (ret == null) {\r
- throw new RoutingException("Impossible do routing. [Hit: Neighbour links (maybe) not yet online.");\r
- }\r
-\r
- return ret;\r
- }\r
-\r
- /**\r
- *\r
- * @param neighbourNode Neighbour Node\r
- * @return true if the node is a left neighbour (or itself), false if it is a right one\r
- */\r
- public static boolean isLeftNeighbour(Node rootNode, Node neighbourNode) {\r
- SymphonyProtocol rootSymphony = (SymphonyProtocol) rootNode.getProtocol(pid);\r
- SymphonyProtocol neighbourSymphony = (SymphonyProtocol) neighbourNode.getProtocol(pid);\r
-\r
- return isLeftNeighbour(rootSymphony.getIdentifier(), neighbourSymphony.getIdentifier());\r
- }\r
-\r
- public static boolean isLeftNeighbour(double rootIdentifier, double neighbourIdentifier) {\r
-\r
- // I calculate putting the hypotesis that i have to translate/"normalize", after i'll check if it was useless\r
- double traslateRootIdentifier = (rootIdentifier + 0.5) % 1;\r
- double traslateNeighbourIdentifier = (neighbourIdentifier + 0.5) % 1;\r
- double distance = traslateNeighbourIdentifier - traslateRootIdentifier;\r
-\r
- // I verify if the neighbourIdentifier is over half ring, if yes i don't need to do the translation/"normalization"\r
- if ((neighbourIdentifier + 0.5) != traslateNeighbourIdentifier) {\r
- distance = neighbourIdentifier - rootIdentifier;\r
- }\r
-\r
- return distance >= 0 && distance <= 0.5;\r
- }\r
-\r
- public void route(Node src, double key, Handler handler) throws RoutingException {\r
-\r
- mapHandler.put(key, handler);\r
-\r
- Message msg = new Message(key, src, MessageType.ROUTE);\r
-\r
- Node targetNode = src;\r
-\r
- if (!isManagerOf(key)) {\r
- targetNode = getCandidateForRouting(key);\r
- Transport transport = (Transport) src.getProtocol(transportID);\r
- transport.send(src, targetNode, msg, pid);\r
- }\r
-\r
- // Insert the message into the chronology\r
- Tuple<Message, Message> historyTuple = new Tuple<Message, Message>();\r
- try {\r
- historyTuple.x = msg;\r
- historyTuple.y = (Message) msg.clone();\r
- historyTuple.y.setCurrentHop(targetNode);\r
- } catch (CloneNotSupportedException ex) {\r
- Logger.getLogger(SymphonyProtocol.class.getName()).log(Level.SEVERE, "Impossible to clonate the message!");\r
- historyTuple.x = null;\r
- historyTuple.y = msg;\r
- msg.setCurrentHop(targetNode);\r
- }\r
- messageHistory.add(new SoftReference<Tuple<Message, Message>>(historyTuple));\r
- messageHistoryID.add(msg.getID());\r
-\r
- /*\r
- *\r
- * If i am the manager (brutally through the reference), i don't do the loopback routing but\r
- * i soddisfy immediately the request\r
- */\r
- if (targetNode == src) {\r
-\r
- // Uppdate the chronology\r
- historyTuple.y = new Message(key, targetNode, MessageType.ROUTE_RESPONSE);\r
-\r
- Tuple<Node, Double> tuple = new Tuple<Node, Double>(src, key);\r
- mapHandler.remove(key);\r
- handler.handle(this, tuple);\r
- }\r
- }\r
-\r
- public void processEvent(Node node, int pid, Object event) {\r
- Message msg = (Message) event;\r
- msg.incrementHop(); // I increment the message Hop\r
-\r
- Tuple<Message, Message> historyTuple = new Tuple<Message, Message>();\r
- try {\r
- // I clone the message such a way to store into the chronology the hop sender's information\r
- historyTuple.x = (Message) msg.clone();\r
- } catch (CloneNotSupportedException ex) {\r
- Logger.getLogger(SymphonyProtocol.class.getName()).log(Level.SEVERE, "Impossible to clonate the message!");\r
- historyTuple.x = msg;\r
- }\r
-\r
- messageHistory.add(new SoftReference<Tuple<Message, Message>>(historyTuple));\r
-\r
- Double key;\r
- Transport transport;\r
- Handler handler;\r
-\r
- // Individuate cycles\r
- if (messageHistoryID.contains(msg.getID())) {\r
- Message responseMsg = new Message(msg, node, MessageType.ROUTE_FAIL);\r
-\r
- historyTuple.y = responseMsg;\r
-\r
- transport = (Transport) node.getProtocol(transportID);\r
- transport.send(node, msg.getSourceNode(), responseMsg, pid);\r
- return;\r
- }\r
-\r
- /*\r
- * If i'm arrived till here means that i'm not into a cycle --> i insert the message ID into\r
- * the chronology\r
- */\r
- messageHistoryID.add(msg.getID());\r
-\r
- switch (msg.getType()) {\r
- case ROUTE:\r
- key = (Double) msg.getBody();\r
- Logger.getLogger(SymphonyProtocol.class.getName()).log(Level.FINEST, key + " " + identifier);\r
- if (isManagerOf(key)) {\r
- transport = (Transport) msg.getSourceNode().getProtocol(transportID);\r
- Message responseMsg = new Message(new Tuple<Node, Double>(node, key), node, MessageType.ROUTE_RESPONSE);\r
- historyTuple.y = responseMsg;\r
- transport.send(node, msg.getSourceNode(), responseMsg, pid);\r
- } else {\r
- try {\r
- Node targetNode = getCandidateForRouting(key);\r
-\r
- try {\r
- // I clone the message such a way to store the info (into the chronology) of the hop receiver\r
- historyTuple.y = (Message) msg.clone();\r
- historyTuple.y.setCurrentHop(targetNode);\r
- } catch (CloneNotSupportedException ex) {\r
- Logger.getLogger(SymphonyProtocol.class.getName()).log(Level.SEVERE, "Impossible to clonate the message!");\r
- historyTuple.y = msg;\r
- msg.setCurrentHop(targetNode);\r
- }\r
-\r
- transport = (Transport) node.getProtocol(transportID);\r
- transport.send(node, targetNode, msg, pid);\r
- } catch (RoutingException ex) {\r
- /*\r
- *\r
- * I send the same message to myself (it is going to queue into the event\r
- * queue and in this way i "earn" time (postpone) and i hope that the\r
- * network will be ok in the meanwhile)\r
- */\r
- historyTuple.y = msg;\r
- msg.setCurrentHop(node);\r
- transport = (Transport) node.getProtocol(transportID);\r
- transport.send(node, node, msg, pid);\r
- }\r
- }\r
- break;\r
- case ROUTE_RESPONSE:\r
- Tuple<Node, Double> tuple = (Tuple<Node, Double>) msg.getBody();\r
- key = tuple.y;\r
- handler = mapHandler.get(key);\r
- mapHandler.remove(key);\r
- handler.handle(this, tuple);\r
- break;\r
- case ROUTE_FAIL:\r
- Message requestMsg = (Message) msg.getBody();\r
- key = (Double) requestMsg.getBody();\r
- handler = mapHandler.get(key);\r
- mapHandler.remove(key);\r
- handler.handle(this, null);\r
- break;\r
- }\r
- }\r
-\r
- public boolean isManagerOf(double key) {\r
-\r
- if (key == identifier) {\r
- return true;\r
- }\r
-\r
- SymphonyNodeComparator comparator = new SymphonyNodeComparator(pid, identifier);\r
- AdapterSymphonyNodeComparator adapterComparator = new AdapterSymphonyNodeComparator(comparator);\r
-\r
- Collection<Tuple<Node, BootstrapStatus>> leftShortRangeLinksCloned = (Collection<Tuple<Node, BootstrapStatus>>) leftShortRangeLinks.clone();\r
- Node targetNode = null;\r
-\r
- while (targetNode == null && !leftShortRangeLinksCloned.isEmpty()) {\r
- Tuple<Node, BootstrapStatus> nearTuple = Collections.min(leftShortRangeLinksCloned, adapterComparator);\r
- if (nearTuple.y == BootstrapStatus.ONLINE) {\r
- targetNode = nearTuple.x;\r
- } else {\r
- leftShortRangeLinksCloned.remove(nearTuple);\r
- }\r
- }\r
-\r
- // SPECIAL CASE: NO LEFT NEIGHBOURS. I became the Manager.\r
- if (targetNode == null) {\r
- return true;\r
- }\r
-\r
- SymphonyProtocol symphony = (SymphonyProtocol) targetNode.getProtocol(pid);\r
- // Check if it's the situation: right neighbour - key - me. So if i'm the manager or not.\r
- boolean ret = isLeftNeighbour(identifier, key) && (!isLeftNeighbour(symphony.getIdentifier(), key) && symphony.getIdentifier() != key);\r
-\r
- return ret;\r
- }\r
-\r
- public double getIdentifier() {\r
- return identifier;\r
- }\r
-\r
- public Tuple<Message, Message>[] getHistoryMessage() {\r
- SoftReference<Tuple<Message, Message>>[] array = messageHistory.toArray(new SoftReference[0]);\r
- LinkedList<Tuple<Message, Message>> list = new LinkedList<Tuple<Message, Message>>();\r
- for (SoftReference<Tuple<Message, Message>> reference : array) {\r
- Tuple<Message, Message> tuple = reference.get();\r
- if (tuple != null) {\r
- list.add(tuple);\r
- }\r
- }\r
- return list.toArray(new Tuple[0]);\r
- }\r
-\r
- public void clearHistoryMessage() {\r
- messageHistory.clear();\r
- }\r
-\r
- private double generateUniqueIdentifier() {\r
- boolean duplicated = true;\r
- Double id = null;\r
-\r
- while (duplicated) {\r
- id = CommonState.r.nextDouble();\r
- duplicated = allIdentifier.contains(id);\r
- }\r
-\r
- allIdentifier.add(id);\r
-\r
- return id;\r
- }\r
-\r
- @Override\r
- public Object clone() {\r
- SymphonyProtocol dolly = new SymphonyProtocol(prefix);\r
- return dolly;\r
- }\r
-\r
- public boolean isBootstrapped() {\r
- return loggedIntoNetwork == BootstrapStatus.ONLINE;\r
- }\r
-}\r
+++ /dev/null
-package example.symphony;\r
-\r
-import peersim.config.Configuration;\r
-import peersim.core.Control;\r
-import peersim.core.Network;\r
-import peersim.core.Node;\r
-\r
-/**\r
- *\r
- * @author Andrea Esposito <and1989@gmail.com>\r
- */\r
-public class SymphonyStatistics implements Control {\r
-\r
- private static final String PAR_SYMPHONY = "symphony";\r
- private final int symphonyID;\r
- private long totalMsg = 0;\r
- private long numRouteResposeMsg = 0;\r
- private long numRouteMsg = 0;\r
- private long numRouteFailMsg = 0;\r
- private long numRouteFoundManagerMsg = 0;\r
- private double mediaHopRouteResponseMsg = 0.0;\r
-\r
- public SymphonyStatistics(String prefix) {\r
- symphonyID = Configuration.getPid(prefix + "." + PAR_SYMPHONY);\r
- }\r
-\r
- public boolean execute() {\r
-\r
- AdapterIterableNetwork itNetwork = new AdapterIterableNetwork();\r
- for (Node node : itNetwork) {\r
- SymphonyProtocol symphony = (SymphonyProtocol) node.getProtocol(symphonyID);\r
- Tuple<Message, Message>[] tupleMessages = symphony.getHistoryMessage();\r
- totalMsg += tupleMessages.length;\r
-\r
- for (Tuple<Message, Message> tupleMessage : tupleMessages) {\r
-\r
- Message message = tupleMessage.x;\r
-\r
- if (message != null) {\r
- switch (message.getType()) {\r
- case ROUTE:\r
- numRouteMsg++;\r
- if (tupleMessage.y != null && tupleMessage.y.getType() == Message.MessageType.ROUTE_RESPONSE) {\r
- numRouteFoundManagerMsg++;\r
- mediaHopRouteResponseMsg = ((mediaHopRouteResponseMsg * (numRouteFoundManagerMsg - 1)) + message.getHop()) / (double) numRouteFoundManagerMsg;\r
- }\r
- break;\r
- case ROUTE_FAIL:\r
- numRouteFailMsg++;\r
- break;\r
- case ROUTE_RESPONSE:\r
- numRouteResposeMsg++;\r
- break;\r
- }\r
- }\r
- }\r
-\r
- symphony.clearHistoryMessage();\r
- }\r
-\r
- printStatistics();\r
-\r
- return false;\r
- }\r
-\r
- private void printStatistics() {\r
- System.out.println("### Statistics ###");\r
- System.out.println("- Total Messages: " + totalMsg);\r
- System.out.println("- Total Route Messages: " + numRouteMsg);\r
- System.out.println("- Found Manager Route Message: " + numRouteFoundManagerMsg);\r
- System.out.println("- Response Message: " + numRouteResposeMsg);\r
- System.out.println("- Fail Message: " + numRouteFailMsg);\r
- System.out.println();\r
- System.out.println("Average Hop:" + mediaHopRouteResponseMsg + " Expected value (k = log n): " + (Math.log(Network.size()) / Math.log(2)));\r
- System.out.println("### END ###\n");\r
- }\r
-}\r
+++ /dev/null
-package example.symphony;\r
-\r
-/**\r
- *\r
- * @author Andrea Esposito <and1989@gmail.com>\r
- */\r
-public class Tuple<X, Y> {\r
-\r
- public X x;\r
- public Y y;\r
-\r
- public Tuple() {\r
- }\r
-\r
- public Tuple(X x, Y y) {\r
- this.x = x;\r
- this.y = y;\r
- }\r
-\r
- @Override\r
- public boolean equals(Object obj) {\r
-\r
- if (obj instanceof Tuple) {\r
- Tuple tuple = (Tuple) obj;\r
-\r
- // (x != null && tuple.x != null) ==> (x==tuple.x || x.equals(tuple.x))\r
- // x == null <==> tuple.x == null\r
-\r
- boolean equalsX = (x == null && tuple.x == null) || ((x != null && tuple.x != null) && (x == tuple.x || x.equals(tuple.x)));\r
- boolean equalsY = (y == null && tuple.y == null) || ((y != null && tuple.y != null) && (y == tuple.y || y.equals(tuple.y)));\r
-\r
- return equalsX && equalsY;\r
- }\r
-\r
- return false;\r
- }\r
-\r
- @Override\r
- public int hashCode() {\r
- int hash = 5;\r
- hash = 89 * hash + (this.x != null ? this.x.hashCode() : 0);\r
- hash = 89 * hash + (this.y != null ? this.y.hashCode() : 0);\r
- return hash;\r
- }\r
-}\r
+++ /dev/null
-package example.symphony.test;\r
-\r
-import example.symphony.AdapterIterableNetwork;\r
-import example.symphony.SymphonyNetworkManager;\r
-import example.symphony.SymphonyProtocol;\r
-import peersim.config.Configuration;\r
-import peersim.core.Control;\r
-import peersim.core.Node;\r
-\r
-/**\r
- *\r
- * @author Andrea Esposito <and1989@gmail.com>\r
- */\r
-public class NetworkEstimationTest implements Control {\r
-\r
- private static final String PAR_NETMANAGER = "symphonynetworkmanager";\r
- private static final String PAR_SYMPHONY = "symphony";\r
- private final int symphonyID;\r
- private final int networkManagerID;\r
-\r
- public NetworkEstimationTest(String prefix) {\r
-\r
- networkManagerID = Configuration.getPid(prefix + "." + PAR_NETMANAGER);\r
- symphonyID = Configuration.getPid(prefix + "." + PAR_SYMPHONY);\r
- }\r
-\r
- public boolean execute() {\r
-\r
- AdapterIterableNetwork it = new AdapterIterableNetwork();\r
- int max = Integer.MIN_VALUE;\r
- int min = Integer.MAX_VALUE;\r
- int sum = 0;\r
- int total = 0;\r
- for (Node node : it) {\r
- if (node.isUp() && ((SymphonyProtocol) node.getProtocol(symphonyID)).isBootstrapped()) {\r
- SymphonyNetworkManager networkManager = (SymphonyNetworkManager) node.getProtocol(networkManagerID);\r
- int n = networkManager.getN();\r
- min = n < min ? n : min;\r
- max = n > max ? n : max;\r
- sum += n;\r
- total++;\r
- }\r
- }\r
-\r
- System.out.println("Real Dimension: " + (Math.log(total) / Math.log(2)));\r
- System.out.println("Average Estimated Dimension: " + (total == 0 ? "No Node online" : (Math.log((sum / total)) / Math.log(2))));\r
- System.out.println("MAX: " + Math.log(max) / Math.log(2));\r
- System.out.println("MIN: " + Math.log(min) / Math.log(2));\r
-\r
- return false;\r
- }\r
-}\r
+++ /dev/null
-/*
- * 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;
-
-import psgsim.PSGSimulator;
-
-import java.io.*;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-import org.simgrid.msg.HostNotFoundException;
-import org.simgrid.msg.NativeException;
-
-import peersim.cdsim.*;
-import peersim.config.*;
-import peersim.core.*;
-import peersim.edsim.*;
-
-/**
- * This is the main entry point to peersim. This class loads configuration and
- * detects the simulation type. According to this, it invokes the appropriate
- * simulator. The known simulators at this moment, along with the way to detect
- * them are the following:
- * <ul>
- * <li>{@link CDSimulator}: if {@link CDSimulator#isConfigurationCycleDriven}
- * returns true</li>
- * <li>{@link EDSimulator}: if {@link EDSimulator#isConfigurationEventDriven}
- * returns true</li>
- * </ul>
- * This list represents the order in which these alternatives are checked. That
- * is, if more than one return true, then the first will be taken. Note that
- * this class checks only for these clues and does not check if the
- * configuration is consistent or valid.
- *
- * @see #main
- */
-public class Simulator {
-
- // ========================== static constants ==========================
- // ======================================================================
- public static int nbreR = 0;
- /** {@link CDSimulator} */
- public static final int CDSIM = 0;
-
- /** {@link EDSimulator} */
- public static final int EDSIM = 1;
-
- /** {@link psgsim.PSGSimulator} */
- public static final int PSGSIM = 2;
-
- /** Unknown simulator */
- public static final int UNKNOWN = -1;
-
- /** the class names of simulators used */
- protected static final String[] simName = { "peersim.cdsim.CDSimulator",
- "peersim.edsim.EDSimulator", "psgsim.PSGSimulator" };
-
- /**
- * Parameter representing the number of times the experiment is run.
- * Defaults to 1.
- *
- * @config
- */
- public static final String PAR_EXPS = "simulation.experiments";
-
- /**
- * If present, this parameter activates the redirection of the standard
- * output to a given PrintStream. This comes useful for processing the
- * output of the simulation from within the simulator.
- *
- * @config
- */
- public static final String PAR_REDIRECT = "simulation.stdout";
-
- // ==================== static fields ===================================
- // ======================================================================
-
- /** */
- private static int simID = UNKNOWN;
-
- // ========================== methods ===================================
- // ======================================================================
-
- /**
- * Returns the numeric id of the simulator to invoke. At the moment this can
- * be {@link #CDSIM}, {@link #EDSIM} or {@link #UNKNOWN}.
- */
- public static int getSimID() {
-
- if (simID == UNKNOWN) {
- if (CDSimulator.isConfigurationCycleDriven()) {
- simID = CDSIM;
- } else if (EDSimulator.isConfigurationEventDriven()) {
- simID = EDSIM;
- } else
- simID = PSGSIM;
-
- }
- return simID;
- }
-
- // ----------------------------------------------------------------------
-
- /**
- * Loads the configuration and executes the experiments. The number of
- * independent experiments is given by config parameter {@value #PAR_EXPS}.
- * In all experiments the configuration is the same, only the random seed is
- * not re-initialized between experiments.
- * <p>
- * Loading the configuration is currently done with the help of constructing
- * an instance of {@link ParsedProperties} using the constructor
- * {@link ParsedProperties#ParsedProperties(String[])}. The parameter
- * <code>args</code> is simply passed to this class. This class is then used
- * to initialize the configuration.
- * <p>
- * After loading the configuration, the experiments are run by invoking the
- * appropriate engine, which is identified as follows:
- * <ul>
- * <li>{@link CDSimulator}: if
- * {@link CDSimulator#isConfigurationCycleDriven} returns true</li>
- * <li>{@link EDSimulator}: if
- * {@link EDSimulator#isConfigurationEventDriven} returns true</li>
- * </ul>
- * <p>
- * This list represents the order in which these alternatives are checked.
- * That is, if more than one return true, then the first will be taken. Note
- * that this class checks only for these clues and does not check if the
- * configuration is consistent or valid.
- *
- * @param args
- * passed on to
- * {@link ParsedProperties#ParsedProperties(String[])}
- * @throws InterruptedException
- * @throws HostNotFoundException
- * @see ParsedProperties
- * @see Configuration
- * @see CDSimulator
- * @see EDSimulator
- */
- public static void main(String[] args) throws InterruptedException,
- HostNotFoundException {
- long time = System.currentTimeMillis();
- long start;
- System.err.println("Simulator: loading configuration");
- Configuration.setConfig(new ParsedProperties(args));
- PrintStream newout = (PrintStream) Configuration.getInstance(
- PAR_REDIRECT, System.out);
- if (newout != System.out)
- System.setOut(newout);
-
- int exps = Configuration.getInt(PAR_EXPS, 1);
- final int SIMID = getSimID();
- if (SIMID == UNKNOWN) {
- System.err
- .println("Simulator: unable to determine simulation engine type");
- return;
- }
-
- try {
-
- for (int k = 0; k < exps; ++k) {
- if (k > 0) {
- long seed = CommonState.r.nextLong();
- CommonState.initializeRandom(seed);
- }
- System.err.print("Simulator: starting experiment " + k);
- System.err.println(" invoking " + simName[SIMID]);
- System.err.println("Random seed: "
- + CommonState.r.getLastSeed());
- // XXX could be done through reflection, but
- // this is easier to read.
-
- switch (SIMID) {
- case CDSIM:
- CDSimulator.nextExperiment();
- break;
- case EDSIM:
- log("ps");
- start = System.currentTimeMillis();
- EDSimulator.nextExperiment();
- System.err.print("Duration of Simulation in ps:"
- + (System.currentTimeMillis() - start) + " ms\n");
- break;
- case PSGSIM:
- try {
- log("psg");
- start = System.currentTimeMillis();
- PSGSimulator.main();
- System.err.print("Duration of Simulation in psg:"
- + (System.currentTimeMillis() - start)
- + " ms\n");
- } catch (NativeException e) {
- System.err
- .println("***********Native exception***************");
- e.printStackTrace();
- }
- break;
- }
- }
-
- } catch (MissingParameterException e) {
- System.err.println(e + "");
- System.exit(1);
- } catch (IllegalParameterException e) {
- System.err.println(e + "");
- System.exit(1);
- }
-
- // undocumented testing capabilities
- if (Configuration.contains("__t"))
- System.out.println(System.currentTimeMillis() - time);
- if (Configuration.contains("__x"))
- Network.test();
-
- }
-
- /**
- *
- * @param sim
- */
- public static void log(String sim) {
- String propName = "OutputName";
-
- /** le nom de l'OS */
- final String OS_NAME = System.getProperty("os.name");
- File file = null;
- String prot = Configuration.getString(propName, "null");
- if (prot.contentEquals("null")) {
- System.err.println("OutputName parameter not defined");
- } else {
- if ("Linux".equals(OS_NAME) || "Mac".equals(OS_NAME)) {
- if (!new File("outputs" + prot).exists()) {
- new File("outputs/" + prot).mkdirs();
- }
- String path = "outputs/" + prot + "/";
- file = new File(path + sim + ".txt");
- } else {
- if (!new File("outputs" + prot).exists())
- new File("outputs\\" + prot).mkdirs();
- String path = "outputs\\" + prot + "\\";
- file = new File(path + sim + ".txt");
- }
- try {
- PrintStream printStream = new PrintStream(file);
- System.setOut(printStream);
- // System.setErr(printStream);
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
- }
-
- }
-
-}
+++ /dev/null
-/*
- * 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.cdsim;
-
-import peersim.core.Protocol;
-import peersim.core.Node;
-
-/**
-* Defines cycle driven protocols, that is, protocols that have a periodic
-* activity in regular time intervals.
-*/
-public interface CDProtocol extends Protocol
-{
-
-/**
- * A protocol which is defined by performing an algorithm in more or less
- * regular periodic intervals.
- * This method is called by the simulator engine once in each cycle with
- * the appropriate parameters.
- *
- * @param node
- * the node on which this component is run
- * @param protocolID
- * the id of this protocol in the protocol array
- */
-public void nextCycle(Node node, int protocolID);
-
-}
+++ /dev/null
-/*
- * 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.cdsim;
-
-import java.util.*;
-import peersim.config.*;
-import peersim.core.*;
-
-/**
- * This is the cycle driven simulation engine. It is a fully static
- * singleton class. For a cycle driven simulation the configuration can
- * describe a set of {@link Protocol}s, and their ordering, a set of
- * {@link Control}s and their ordering and a set of initializers and their
- * ordering. See parameters {@value #PAR_INIT}, {@value #PAR_CTRL}. Out
- * of the set of protocols, this engine only executes the ones that
- * implement the {@link CDProtocol} interface.
- * <p>
- * One experiment run by {@link #nextExperiment} works as follows. First
- * the initializers are run in the specified order, then the following is
- * iterated {@value #PAR_CYCLES} times: If {@value #PAR_NOMAIN} is
- * specified, then simply the controls specified in the configuration are
- * run in the specified order. If {@value #PAR_NOMAIN} is not specified,
- * then the controls in the configuration are run in the specified order,
- * followed by the execution of {@link FullNextCycle}.
- * <p>
- * All components (controls and protocols) can have configuration
- * parameters that control their scheduling (see {@link Scheduler}). This
- * way they can skip cycles, start from a specified cycle, etc. As a
- * special case, components can be scheduled to run after the last cycle.
- * That is, each experiment is finished by running the controls that are
- * scheduled after the last cycle.
- * <p>
- * Finally, any control can interrupt an experiment at any time it is
- * executed by returning true in method {@link Control#execute}. However,
- * the controls scheduled to run after the last cycle are still executed
- * completely, irrespective of their return value and even if the
- * experiment was interrupted.
- * @see Configuration
- */
-public class CDSimulator
-{
-
-// ============== fields ===============================================
-// =====================================================================
-
-/**
- * Parameter representing the maximum number of cycles to be performed
- * @config
- */
-public static final String PAR_CYCLES = "simulation.cycles";
-
-/**
- * This option is only for experts. It switches off the main cycle that
- * calls the cycle driven protocols. When you switch this off, you need to
- * control the execution of the protocols by configuring controls that do
- * the job (e.g., {@link FullNextCycle}, {@link NextCycle}). It's there for
- * people who want maximal flexibility for their hacks.
- * @config
- */
-private static final String PAR_NOMAIN = "simulation.nodefaultcycle";
-
-/**
- * This is the prefix for initializers. These have to be of type
- * {@link Control}. They are run at the beginning of each experiment, in
- * the order specified by the configuration.
- * @see Configuration
- * @config
- */
-private static final String PAR_INIT = "init";
-
-/**
- * This is the prefix for controls. These have to be of type
- * {@link Control}. They are run before each cycle, in the order specified
- * by the configuration.
- * @see Configuration
- * @config
- */
-private static final String PAR_CTRL = "control";
-
-// --------------------------------------------------------------------
-
-/** The maximum number of cycles to be performed */
-private static int cycles;
-
-/** holds the modifiers of this simulation */
-private static Control[] controls = null;
-
-/** Holds the control schedulers of this simulation */
-private static Scheduler[] ctrlSchedules = null;
-
-// =============== initialization ======================================
-// =====================================================================
-
-/** to prevent construction */
-private CDSimulator()
-{
-}
-
-// =============== private methods =====================================
-// =====================================================================
-
-/**
- * Load and run initializers.
- */
-private static void runInitializers()
-{
-
- Object[] inits = Configuration.getInstanceArray(PAR_INIT);
- String names[] = Configuration.getNames(PAR_INIT);
-
- for (int i = 0; i < inits.length; ++i) {
- System.err.println("- Running initializer " + names[i] + ": "
- + inits[i].getClass());
- ((Control) inits[i]).execute();
- }
-}
-
-// --------------------------------------------------------------------
-
-private static String[] loadControls()
-{
-
- boolean nomaincycle = Configuration.contains(PAR_NOMAIN);
- String[] names = Configuration.getNames(PAR_CTRL);
- if (nomaincycle) {
- controls = new Control[names.length];
- ctrlSchedules = new Scheduler[names.length];
- } else {
- // provide for an extra control that handles the main cycle
- controls = new Control[names.length + 1];
- ctrlSchedules = new Scheduler[names.length + 1];
- // calling with a prefix that cannot exist
- controls[names.length] = new FullNextCycle(" ");
- ctrlSchedules[names.length] = new Scheduler(" ");
- }
- for (int i = 0; i < names.length; ++i) {
- controls[i] = (Control) Configuration.getInstance(names[i]);
- ctrlSchedules[i] = new Scheduler(names[i]);
- }
- System.err.println("CDSimulator: loaded controls " + Arrays.asList(names));
- return names;
-}
-
-// ---------------------------------------------------------------------
-
-/**
- * This method is used to check whether the current configuration can be
- * used for cycle-driven simulations. It checks for the existence of
- * configuration parameter {@value #PAR_CYCLES}.
- */
-public static final boolean isConfigurationCycleDriven()
-{
- return Configuration.contains(PAR_CYCLES);
-}
-
-// ---------------------------------------------------------------------
-
-/**
- * Runs an experiment, resetting everything except the random seed.
- */
-public static final void nextExperiment()
-{
-
- // Reading parameter
- cycles = Configuration.getInt(PAR_CYCLES);
- if (CommonState.getEndTime() < 0) // not initialized yet
- CDState.setEndTime(cycles);
-
- // initialization
- CDState.setCycle(0);
- CDState.setPhase(CDState.PHASE_UNKNOWN);
- System.err.println("CDSimulator: resetting");
- controls = null;
- ctrlSchedules = null;
- Network.reset();
- System.err.println("CDSimulator: running initializers");
- runInitializers();
-
- // main cycle
- loadControls();
-
- System.err.println("CDSimulator: starting simulation");
- for (int i = 0; i < cycles; ++i) {
- CDState.setCycle(i);
-
- boolean stop = false;
- for (int j = 0; j < controls.length; ++j) {
- if (ctrlSchedules[j].active(i))
- stop = stop || controls[j].execute();
- }
- if (stop)
- break;
- //System.err.println("CDSimulator: cycle " + i + " DONE");
- }
-
- CDState.setPhase(CDState.POST_SIMULATION);
-
- // analysis after the simulation
- for (int j = 0; j < controls.length; ++j) {
- if (ctrlSchedules[j].fin)
- controls[j].execute();
- }
-}
-
-}
+++ /dev/null
-/*
- * 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.cdsim;
-
-import peersim.core.CommonState;
-
-
-/**
- * This is the common state of a cycle driven simulation that all objects see.
- * It contains additional information, specific to the cycle driven model,
- * in addition to the info in {@link peersim.core.CommonState}.
- */
-public class CDState extends CommonState {
-
-
-// ======================= fields ==================================
-// =================================================================
-
-/**
- * Current time within the current cycle.
- * Note that {@link #cycle} gives the cycle id to which this value is relative.
- */
-private static int ctime = -1;
-
-/**
- * Current cycle in the simulation. It makes sense only in the case of a
- * cycle based simulator, that is, cycle based simulators will maintain this
- * value, others will not. It still makes sense to keep it separate from
- * {@link #time} because it is an int, while time is a long.
- */
-private static int cycle = -1;
-
-
-// ======================== initialization =========================
-// =================================================================
-
-
-static {}
-
-/** to avoid construction */
-private CDState() {}
-
-// ======================= methods =================================
-// =================================================================
-
-
-/**
-* Returns true if and only if there is a cycle driven simulation going on.
-*/
-public static boolean isCD() { return cycle >= 0; }
-
-//-----------------------------------------------------------------
-
-/**
- * Returns the current cycle.
- * Note that {@link #getTime()} returns the same value.
- * @throws UnsupportedOperationException if no cycle-driven state is available
- */
-public static int getCycle()
-{
- if( cycle >= 0 ) return cycle;
- else throw new UnsupportedOperationException(
- "Cycle driven state accessed when "+
- "no cycle state information is available.");
-}
-
-//-----------------------------------------------------------------
-
-/**
- * Sets current cycle. Resets also cycle time to 0. It also calls
- * {@link #setTime(long)} with the given parameter, to make sure
- * {@link #getTime()} is indeed independent of the simulation model.
- */
-public static void setCycle(int t)
-{
- cycle = t;
- ctime = 0;
- setTime(t);
-}
-
-//-----------------------------------------------------------------
-
-/**
- * Returns current cycle as an Integer object.
- * @throws UnsupportedOperationException if no cycle-driven state is available
- */
-public static Integer getCycleObj()
-{
- if( cycle >= 0 ) return Integer.valueOf(cycle);
- else throw new UnsupportedOperationException(
- "Cycle driven state accessed when "+
- "no cycle state information is available.");
-}
-
-//-----------------------------------------------------------------
-
-/**
- * Returns the current time within the current cycle.
- * Note that the time returned by {@link #getCycle} is the cycle id
- * in this case. In other words, it returns the number of nodes that have
- * already been visited in a given cycle.
- * @throws UnsupportedOperationException if no cycle-driven state is available
- */
-public static int getCycleT()
-{
- if( ctime >= 0 ) return ctime;
- else throw new UnsupportedOperationException(
- "Cycle driven state accessed when "+
- "no cycle state information is available.");
-}
-
-// -----------------------------------------------------------------
-
-public static void setCycleT(int t)
-{
- ctime = t;
-}
-}
-
-
+++ /dev/null
-/*
- * 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.cdsim;
-
-import java.util.Arrays;
-import peersim.config.Configuration;
-import peersim.core.Node;
-import peersim.core.Control;
-
-/**
-* A protocol that is not really a protocol, but a trick to carry out all
-* kinds of tasks during the simulation. Many users will probably not need it,
-* but it is a nice way to e.g. run controls at any time, not only between cycles.
-*/
-public class DaemonProtocol implements CDProtocol {
-
-
-// ========================= fields =================================
-// ==================================================================
-
-
-/**
-* This is the prefix for network dynamism managers.
-* @config
-*/
-private static final String PAR_CTRL = "control";
-
-/**
-* The controls will be run according to this frequency.
-* It is interpreted within a cycle, in terms of cycle time
-* ({@link CDState#getCycleT}). The first cycletime is 0.
-* Defaults to 1.
-* @config
-*/
-private static final String PAR_STEP = "cstep";
-
-// --------------------------------------------------------------------
-
-private static Control[] controls=null;
-
-private static int step;
-
-// ========================= initialization =========================
-// ==================================================================
-
-
-public DaemonProtocol(String s)
-{
- step = Configuration.getInt(s+"."+PAR_STEP,1);
-
- String[] names = Configuration.getNames(s+"."+PAR_CTRL);
- controls = new Control[names.length];
- for(int i=0; i<names.length; ++i)
- {
- controls[i]=(Control)Configuration.getInstance(names[i]);
- }
- System.err.println(s+": loaded controls "+Arrays.asList(names));
-}
-
-// ------------------------------------------------------------------
-
-public Object clone() {
-
- DaemonProtocol ip = null;
- try { ip=(DaemonProtocol)super.clone(); }
- catch( CloneNotSupportedException e ) {} // never happens
- return ip;
-}
-
-
-// ========================= methods =================================
-// ===================================================================
-
-
-/**
-* Runs the configured controls if {@link CDState#getCycleT} %
-* {@value #PAR_STEP}=0.
-*/
-public void nextCycle( Node node, int protocolID ) {
-
- if( CDState.getCycleT() % step != 0 ) return;
- for(int j=0; j<controls.length; ++j) controls[j].execute();
-}
-
-}
-
+++ /dev/null
-/*
- * 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.cdsim;
-
-import peersim.config.*;
-import peersim.core.*;
-import peersim.util.RandPermutation;
-
-/**
-* Control to run a cycle of the cycle driven simulation.
-* This does not need to be explicitly configured (although you can do it for
-* hacking purposes).
-*/
-public class FullNextCycle implements Control {
-
-
-// ============== fields ===============================================
-// =====================================================================
-
-
-/**
-* The type of the getPair function. This parameter is of historic interest and
-* was needed in a publication we wrote. You don't need to care about this.
-* But if you wanna know: if set to "rand", then in a cycle the simulator
-* does not simply iterate through the nodes, but instead picks a random one
-* N times, where N is the network size.
-* @config
-*/
-private static final String PAR_GETPAIR = "getpair";
-
-/**
-* Shuffle iteration order if set. Not set by default. If set, then nodes are
-* iterated in a random order. However, in the network the nodes actually
-* stay in the order they originally were. The price for leaving the
-* network untouched is memory: we need to store the permutation we use
-* to iterate the network.
-* @config
-*/
-private static final String PAR_SHUFFLE = "shuffle";
-
-// --------------------------------------------------------------------
-
-protected final boolean getpair_rand;
-
-protected final boolean shuffle;
-
-/** Holds the protocol schedulers of this simulation */
-protected Scheduler[] protSchedules = null;
-
-/** The random permutation to use if config par {@value #PAR_SHUFFLE} is set. */
-protected RandPermutation rperm = new RandPermutation( CDState.r );
-
-// =============== initialization ======================================
-// =====================================================================
-
-/**
-* Reads config parameters and {@link Scheduler}s.
-*/
-public FullNextCycle(String prefix) {
-
- getpair_rand = Configuration.contains(prefix+"."+PAR_GETPAIR);
- shuffle = Configuration.contains(prefix+"."+PAR_SHUFFLE);
-
- // load protocol schedulers
- String[] names = Configuration.getNames(Node.PAR_PROT);
- protSchedules = new Scheduler[names.length];
- for(int i=0; i<names.length; ++i)
- {
- protSchedules[i] = new Scheduler(names[i]);
- }
-}
-
-// =============== methods =============================================
-// =====================================================================
-
-/**
- * Execute all the {@link CDProtocol}s on all nodes that are up.
- * If the node goes down as a result of the execution of a protocol, then
- * the rest of the protocols on that node are not executed and we move on
- * to the next node.
- * It sets the {@link CDState} appropriately.
- * @return always false
- */
-public boolean execute() {
-
- final int cycle=CDState.getCycle();
- if( shuffle ) rperm.reset( Network.size() );
- for(int j=0; j<Network.size(); ++j)
- {
- Node node = null;
- if( getpair_rand )
- node = Network.get(CDState.r.nextInt(Network.size()));
- else if( shuffle )
- node = Network.get(rperm.next());
- else
- node = Network.get(j);
- if( !node.isUp() ) continue;
- CDState.setNode(node);
- CDState.setCycleT(j);
- final int len = node.protocolSize();
- for(int k=0; k<len; ++k)
- {
- // Check if the protocol should be executed, given the
- // associated scheduler.
- if (!protSchedules[k].active(cycle))
- continue;
-
- CDState.setPid(k);
- Protocol protocol = node.getProtocol(k);
- if( protocol instanceof CDProtocol )
- {
- ((CDProtocol)protocol).nextCycle(node, k);
- if( !node.isUp() ) break;
- }
- }
- }
-
- return false;
-}
-
-}
+++ /dev/null
-/*
- * 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.cdsim;
-
-import peersim.config.*;
-import peersim.core.*;
-
-/**
-* It generalizes its superclass so that the list of protocols to run can
-* be specified. The superclass ({@link FullNextCycle}) always runs all the
-* {@link CDProtocol}s.
-*/
-public class NextCycle extends FullNextCycle {
-
-
-// ============== fields ===============================================
-// =====================================================================
-
-
-/**
-* Gives the list of protocols (whitespace separated) that need to be
-* iterated over.
-* @config
-*/
-private static final String PAR_PROTS = "protocol";
-
-private final int[] pids;
-
-
-// =============== initialization ======================================
-// =====================================================================
-
-/**
-* reads configuration parameters and the {@link Scheduler}s.
-*/
-public NextCycle(String prefix) {
-
- super(prefix);
-
- String prots = Configuration.getString(prefix+"."+PAR_PROTS);
- String[] protnames = prots.split("\\s");
- pids = new int[protnames.length];
- for(int i=0; i<protnames.length; ++i)
- {
- pids[i] = Configuration.lookupPid(protnames[i]);
- }
-}
-
-// =============== methods =============================================
-// =====================================================================
-
-/**
- * Execute the configured protocols on all nodes.
- * It works exactly as {@link FullNextCycle#execute}, only just the configured
- * protocols are iterated over.
- */
-public boolean execute() {
-
- final int cycle=CDState.getCycle();
- if( shuffle ) rperm.reset( Network.size() );
- for(int j=0; j<Network.size(); ++j)
- {
- Node node = null;
- if( getpair_rand )
- node = Network.get(CDState.r.nextInt(Network.size()));
- else if( shuffle )
- node = Network.get(rperm.next());
- else
- node = Network.get(j);
- if( !node.isUp() ) continue;
- CDState.setNode(node);
- CDState.setCycleT(j);
- for(int pid: pids)
- {
- // Check if the protocol should be executed, given the
- // associated scheduler.
- if (!protSchedules[pid].active(cycle))
- continue;
-
- CDState.setPid(pid);
- Protocol protocol = node.getProtocol(pid);
- if( protocol instanceof CDProtocol )
- {
- ((CDProtocol)protocol).nextCycle(node, pid);
- if( !node.isUp() ) break;
- }
- }
- }
-
- return false;
-}
-
-}
-
-
+++ /dev/null
-/*
- * 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.cdsim;
-
-import peersim.core.*;
-
-/**
-* Shuffles the network. After shuffling, the order in which the nodes
-* are iterated over during a cycle of a cycle driven simulation
-* will be random. It has an effect only in cycle driven simulations.
-*/
-public class Shuffle implements Control {
-
-
-// ========================= fields =================================
-// ==================================================================
-
-// ==================== initialization ==============================
-// ==================================================================
-
-/** Does nothing. */
-public Shuffle(String prefix) {}
-
-
-// ===================== public methods ==============================
-// ===================================================================
-
-
-/**
-* Calls {@link Network#shuffle()}.
-* As a result, the order in which the nodes
-* are iterated over during a cycle of a cycle driven simulation
-* will be random. It has an effect only in cycle driven simulations.
-*/
-public final boolean execute() {
- Network.shuffle();
- return false;
-}
-
-
-}
-
-
+++ /dev/null
-/*
- * 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.config;
-
-import java.util.*;
-
-import peersim.cdsim.*;
-import peersim.edsim.*;
-import peersim.util.*;
-
-
-/**
- * This is utility tool that checks whether a config file can be loaded
- * or not, without actually performing the simulation. All the error
- * messages generated by controls and protocols when initialized are
- * reported. This is useful to check all the configuration files in a
- * directory.
- */
-public class CheckConfig {
-
-//========================== parameters ================================
-//======================================================================
-
-/**
- * This is the prefix of the config properties whose value vary during
- * a set of experiments.
- * @config
- */
-private static final String PAR_RANGE = "range";
-
-
-// ========================== static constants ==========================
-// ======================================================================
-
-/** {@link CDSimulator} */
-protected static final int CDSIM = 0;
-
-/** {@link EDSimulator} */
-protected static final int EDSIM = 1;
-
-protected static final int UNKNOWN = -1;
-
-/** the class names of simulators used */
-protected static final String[] simName = {
- CDSimulator.class.getCanonicalName(),
- EDSimulator.class.getCanonicalName(),
-};
-
-
-
-
-// ========================== methods ===================================
-// ======================================================================
-
-/**
-* Returns the numeric id of the simulator to invoke. At the moment this can
-* be {@link #CDSIM}, {@link #EDSIM} or {@link #UNKNOWN}.
-*/
-protected static int getSimID() {
-
- if( CDSimulator.isConfigurationCycleDriven())
- {
- return CDSIM;
- }
- else if( EDSimulator.isConfigurationEventDriven() )
- {
- return EDSIM;
- }
- else return UNKNOWN;
-}
-
-// ----------------------------------------------------------------------
-
-/**
-* Loads the configuration and checks the configuration files against
-* simple configuration errors, such as missing classes, missing
-* parameters or syntax errors.
-* <p>
-* The goal is to provide a mechanism to test a configuration file,
-* without having to perform the actual simulations (that could be
-* time-consuming) and without necessarily blocking after the first
-* error encountered. It may be useful, for example, when a major
-* refactoring of your code requires a thorough check on all your
-* configuration files.
-* <p>
-* Loading the configuration is currently done with the help of
-* constructing an instance of {@link ParsedProperties} using the
-* constructor {@link ParsedProperties#ParsedProperties(String[])},
-* in the same way as the normal simulator.
-* <p>
-* After loading the configuration, the collection of nodes forming a
-* Network is instantiated, together with all protocols forming a
-* node. Initialization controls are executed, and then the simulation
-* stops.
-* <p>
-* For each error encountered, a message is printed ons standard error,
-* and the initialization keeps going without interruption. If multiple
-* errors are present, an error message for each of them is printed.
-* Apart from errors, default choices are also printed as warnings, to
-* allow developers to spot subtle configuration errors such as missing
-* parameters that defaults to standard values.
-*
-* @param args passed on to
-* {@link ParsedProperties#ParsedProperties(String[])}
-*/
-public static void main(String[] args)
- throws Exception
-{
- System.setErr(new NullPrintStream());
- Properties prop = new ParsedProperties(args);
- Configuration.setConfig( prop, true );
- parseRanges(prop);
-
- final int SIMID = getSimID();
- if( SIMID == UNKNOWN )
- {
- System.err.println(
- "Simulator: unable to identify configuration, exiting.");
- return;
- }
-
- try {
-
- // XXX could be done through reflection, but
- // this is easier to read.
- switch(SIMID)
- {
- case CDSIM:
- // Set cycles to 0, so no simulation is ever performed.
- prop.setProperty(CDSimulator.PAR_CYCLES, "0");
- CDSimulator.nextExperiment();
- break;
- case EDSIM:
- // Set endtime to 0, so no simulation is ever performed.
- prop.setProperty(EDSimulator.PAR_ENDTIME, "0");
- EDSimulator.nextExperiment();
- break;
- }
-
- } catch (MissingParameterException e) {
- System.out.println(e.getMessage());
- System.exit(1);
- } catch (IllegalParameterException e) {
- System.out.println(e.getMessage());
- System.exit(1);
- }
-}
-
-/**
- * Parses a collection of range specifications, identifies the set
- * of parameters that will change during the simulation and
- * instantiates them with the first value of their ranges.
- */
-private static void parseRanges(Properties prop)
-{
- // Get ranges
- String[] ranges = Configuration.getNames(PAR_RANGE);
-
- for (int i = 0; i < ranges.length; i++) {
- String[] array = Configuration.getString(ranges[i]).split(";");
- if (array.length != 2) {
- throw new IllegalParameterException(ranges[i],
- " should be formatted as <parameter>;<value list>");
- }
- String[] values = StringListParser.parseList(array[1]);
- prop.setProperty(array[0], values[0]);
- }
-}
-
-}
+++ /dev/null
-/*
- * 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.config;
-
-import java.io.*;
-import java.util.*;
-import java.util.zip.*;
-
-/**
- * Provides static methods to obtain the package-qualified class name
- * of a class, given just the non-qualified name, and to obtain
- * the non-qualified name, given the package-qualified class name.
- *
- * Inspired from some code written by David Postill (david@postill.org.uk)
- * (found in http://groups.google.com).
- *
- *
- * @author Alberto Montresor
- * @version $Revision: 1.9 $
- */
-class ClassFinder
-{
-
-//--------------------------------------------------------------------------
-//Fields and initialization
-//--------------------------------------------------------------------------
-
-
-/** Local map containing the associations */
-private static Map<String,String> map = new TreeMap<String,String>();
-
-/** The number of directories that have been touched by the search.
-This does not include directories in jar files. */
-private static int visitedDirs = 0;
-
-private static final int maxDirs;
-
-static {
-
- maxDirs = 10000;
-
- try {
- findClasses(map);
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- if(visitedDirs >= maxDirs )
- {
- System.err.println("Configuration: some directories in your "+
- "classpath probably contain filesystem\nConfiguration: "+
- "loops because the number of visited directories "+
- "reached "+maxDirs+".\nConfiguration: This means automatic "+
- "class lookup might fail and you might have\nConfiguration: "+
- "to fully qualify class names in the configuration.");
- }
-}
-
-
-//--------------------------------------------------------------------------
-//Public static methods
-//--------------------------------------------------------------------------
-
-/**
- * Returns the non-qualified name of a class, removing all the package
- * information.
- */
-public static String getShortName(String className) {
-
- int index = className.lastIndexOf('.');
- if (index < 0) {
- return className;
- } else {
- return className.substring(index+1);
- }
-}
-
-/**
- * Returns the package-qualified name associated to the specified
- * non-qualified name, if exists. Otherwise it returns null.
- *
- * Only classes reachable from the classpath defined by the
- * "java.class.path" property are considered.
- * Jar files and directories are both parsed.
- * If multiple classes with the same name but different
- * fully-qualified names are present, a comma-separated list
- * of fully-qualified class names is returned.
- *
- * @param name the non-qualified name of the class to be searched
- * @return the qualified name, if exists.
- */
-public static String getQualifiedName(String name)
-{
- return map.get(name);
-}
-
-//--------------------------------------------------------------------------
-//Private static methods
-//--------------------------------------------------------------------------
-
-/**
- * Finds all the classes reachable from the current classpath;
- * for each of them, inserts an association (name, fully-qualified
- * name) in the specified map. Both names are String objects.
- *
- * Only classes reachable from the classpath defined by the
- * "java.class.path" property are considered.
- * Jar files and directories are both parsed.
- * If multiple classes with the same name but different
- * fully-qualified names are present, they are inserted
- * in the map as associations (name, comma-separated list of
- * fully-qualified names).
- *
- * @param map
- * @throws IOException
- */
-private static void findClasses(Map<String,String> map)
-throws IOException
-{
- String classPath = System.getProperty( "java.class.path" );
- String separator = System.getProperty( "path.separator" );
- String filesep = System.getProperty( "file.separator");
- StringTokenizer path = new StringTokenizer( classPath, separator );
-
- while( path.hasMoreTokens() ) {
-
- String pathElement = path.nextToken();
- File pathFile = new File( pathElement );
-
- if( pathFile.isDirectory() ) {
- if (!pathElement.endsWith(filesep)) {
- pathElement = pathElement + filesep;
- pathFile = new File( pathElement);
- }
- findClassInPathDir( map, pathElement, pathFile );
- // Search directories
- } else if ( pathFile.exists() ) {
- findClassInJar( map, pathFile);
- }
- }
-}
-
-//--------------------------------------------------------------------------
-
-/**
- * Parses jar file.
- *
- * @param map the map where to insert associations
- * @param pathFile the file name of the associated jar file
- * @throws IOException
- */
-private static void findClassInJar(Map<String,String> map, File pathFile)
-throws IOException
-{
- ZipFile zipFile = new ZipFile( pathFile );
- Enumeration entries = zipFile.entries();
- while( entries.hasMoreElements() ) {
-
- String entry = entries.nextElement().toString();
- if( entry.endsWith( ".class" ) ) {
- // File names in ZIP archives (so, also in JARs)
- // are separated by forward slashes '/', independently
- // of the architecture.
- String className = classname( entry, "/" );
- String shortName = getShortName( className );
- if (map.containsKey(shortName)) {
- map.put(shortName,
- map.get(shortName)+","+className);
- } else {
- map.put(shortName, className);
- }
- }
- }
-}
-
-//--------------------------------------------------------------------------
-
-/**
- * Recursively parses directories.
- *
- * @param map the map where to insert associations
- * @param pathElement the path string used for recursion
- * @param pathFile the file (directory) to be analyzed
- * @throws IOException
- */
-private static void findClassInPathDir( Map<String,String> map,
- String pathElement, File pathFile )
-throws IOException
-{
- visitedDirs++;
- if(visitedDirs>=maxDirs) return;
-
- String[] list = pathFile.list();
- String filesep = System.getProperty( "file.separator");
-
- for( int i = 0; i < list.length; i++ ) {
- File file = new File( pathFile, list[i] );
- if( file.isDirectory() ) {
- findClassInPathDir( map, pathElement, file );
- }
- else if ( file.exists() && (file.length() != 0) && list[i].endsWith( ".class" ) ) {
- String classFile = file.toString().substring( pathElement.length());
- String className = classname( classFile, filesep );
- String shortName = getShortName( className );
- if (map.containsKey(shortName)) {
- map.put(shortName, map.get(shortName)+","+className);
- } else {
- map.put(shortName, className);
- }
- }
- }
-}
-
-//--------------------------------------------------------------------------
-
-/**
- * Translates a class file name in a class name using
- * the specified file separator.
- */
-private static String classname(String classFile, String filesep)
-{
- return classFile.replace( filesep, "." ).substring(
- 0, classFile.length() - ".class".length() );
-}
-
-//--------------------------------------------------------------------------
-
-/**
- * Testing.
- *
- * @param argv
- */
-public static void main( String[] argv )
-{
- Iterator i = map.keySet().iterator();
- while (i.hasNext()) {
- String key = (String) i.next();
- String name = map.get(key);
- System.out.println(key + " --> " + name);
- }
-}
-}
+++ /dev/null
-/*
- * 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.config;
-
-import java.lang.reflect.*;
-import java.util.*;
-import org.lsmp.djep.groupJep.*;
-
-/**
- * This class is the container for the configuration data used in
- * {@link Configuration}; see that class for more information.
- */
-public class ConfigContainer
-{
-
-// =================== static fields =================================
-// ===================================================================
-
-/** Symbolic constant for no debug */
-private static final int DEBUG_NO = 0;
-
-/** Symbolic constant for regular debug */
-private static final int DEBUG_REG = 1;
-
-/** Symbolic constant for extended debug */
-private static final int DEBUG_CONTEXT = 2;
-
-//========================== fields =================================
-//===================================================================
-
-/**
- * The properties object that stores all configuration information.
- */
-private Properties config;
-
-/**
- * Map associating string protocol names to the numeric protocol
- * identifiers. The protocol names are understood without prefix.
- */
-private Map<String, Integer> protocols;
-
-/**
- * The maximum depth that can be reached when analyzing expressions. This
- * value can be substituted by setting the configuration parameter
- * PAR_MAXDEPTH.
- */
-private int maxdepth;
-
-/** Debug level */
-private int debugLevel;
-
-/**
- * If true, no exception is thrown. Instead, an error is printed and the
- * Configuration tries to return a reasonable return value
- */
-private boolean check = false;
-
-// =================== initialization ================================
-// ===================================================================
-
-public ConfigContainer(Properties config, boolean check)
-{
- this.config = config;
- this.check = check;
- maxdepth = getInt(Configuration.PAR_MAXDEPTH, Configuration.DEFAULT_MAXDEPTH);
-
- // initialize protocol id-s
- protocols = new HashMap<String, Integer>();
- String[] prots = getNames(Configuration.PAR_PROT);// they're returned in correct order
- for (int i = 0; i < prots.length; ++i) {
- protocols.put(prots[i].substring(Configuration.PAR_PROT.length() + 1), Integer.valueOf(i));
- }
- String debug = config.getProperty(Configuration.PAR_DEBUG);
- if (Configuration.DEBUG_EXTENDED.equals(debug))
- debugLevel = DEBUG_CONTEXT;
- else if (Configuration.DEBUG_FULL.equals(debug)) {
- Map<String, String> map = new TreeMap<String, String>();
- Enumeration e = config.propertyNames();
- while (e.hasMoreElements()) {
- String name = (String) e.nextElement();
- String value = config.getProperty(name);
- map.put(name, value);
- }
- Iterator i = map.keySet().iterator();
- while (i.hasNext()) {
- String name = (String) i.next();
- System.err.println("DEBUG " + name
- + ("".equals(map.get(name)) ? "" : " = " + map.get(name)));
- }
- } else if (debug != null) {
- debugLevel = DEBUG_REG;
- } else {
- debugLevel = DEBUG_NO;
- }
-}
-
-// =================== static public methods =========================
-// ===================================================================
-
-/**
- * @return true if and only if name is a specified (existing) property.
- */
-public boolean contains(String name)
-{
- boolean ret = config.containsKey(name);
- debug(name, "" + ret);
- return ret;
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads given configuration property. If not found, throws a
- * {@link MissingParameterException}.
- * @param name
- * Name of configuration property
- * @param def
- * default value
- */
-public boolean getBoolean(String name, boolean def)
-{
- try {
- return getBool(name);
- } catch (RuntimeException e) {
- manageDefault(name, def, e);
- return def;
- }
-}
-
-// -------------------------------------------------------------------
-
-
-/**
- * Reads given property. If not found, or the value is empty string then
- * throws a {@link MissingParameterException}. Empty string is not
- * accepted as false due to the similar function of {@link #contains} which
- * returns true in that case. True is returned if the lowercase value of
- * the property is "true", otherwise false is returned.
- * @param name
- * Name of configuration property
- */
-public boolean getBoolean(String name)
-{
- try {
- return getBool(name);
- } catch (RuntimeException e) {
- manageException(name, e);
- return false;
- }
-}
-
-//-------------------------------------------------------------------
-
-/**
- * The actual methods that implements getBoolean.
- */
-private boolean getBool(String name)
-{
- if (config.getProperty(name) == null) {
- throw new MissingParameterException(name);
-// "\nPossibly incorrect property: " + getSimilarProperty(name));
- }
- if (config.getProperty(name).matches("\\p{Blank}*")) {
- throw new MissingParameterException(name,
- "Blank value is not accepted when parsing Boolean.");
- }
- boolean ret = Boolean.valueOf(config.getProperty(name));
- debug(name, "" + ret);
- return ret;
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads given configuration property. If not found, returns the default
- * value.
- * @param name
- * Name of configuration property
- * @param def
- * default value
- */
-public int getInt(String name, int def)
-{
- try {
- Number ret = getVal(name, name, 0);
- debug(name, "" + ret);
- return ret.intValue();
- } catch (RuntimeException e) {
- manageDefault(name, def, e);
- return def;
- }
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads given configuration property. If not found, throws a
- * {@link MissingParameterException}.
- * @param name
- * Name of configuration property
- */
-public int getInt(String name)
-{
- try {
- Number ret = getVal(name, name, 0);
- debug(name, "" + ret);
- return ret.intValue();
- } catch (RuntimeException e) {
- manageException(name, e);
- return 0;
- }
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads given configuration property. If not found, returns the default
- * value.
- * @param name
- * Name of configuration property
- * @param def
- * default value
- */
-public long getLong(String name, long def)
-{
- try {
- Number ret = getVal(name, name, 0);
- debug(name, "" + ret);
- return ret.longValue();
- } catch (RuntimeException e) {
- manageDefault(name, def, e);
- return def;
- }
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads given configuration property. If not found, throws a
- * {@link MissingParameterException}.
- * @param name
- * Name of configuration property
- */
-public long getLong(String name)
-{
- try {
- Number ret = getVal(name, name, 0);
- debug(name, "" + ret);
- return ret.longValue();
- } catch (RuntimeException e) {
- manageException(name, e);
- return 0;
- }
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads given configuration property. If not found, returns the default
- * value.
- * @param name
- * Name of configuration property
- * @param def
- * default value
- */
-public double getDouble(String name, double def)
-{
- try {
- Number ret = getVal(name, name, 0);
- debug(name, "" + ret);
- return ret.doubleValue();
- } catch (RuntimeException e) {
- manageDefault(name, def, e);
- return def;
- }
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads given configuration property. If not found, throws a
- * MissingParameterException.
- * @param name
- * Name of configuration property
- */
-public double getDouble(String name)
-{
- try {
- Number ret = getVal(name, name, 0);
- debug(name, "" + ret);
- return ret.doubleValue();
- } catch (RuntimeException e) {
- manageException(name, e);
- return 0;
- }
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Read numeric property values, parsing expression if necessary.
- *
- * @param initial
- * the property name that started this expression evaluation
- * @param property
- * the current property name to be evaluated
- * @param depth
- * the depth reached so far
- * @return the evaluation of the expression associated to property
- */
-private Number getVal(String initial, String property, int depth)
-{
- if (depth > maxdepth) {
- throw new IllegalParameterException(initial,
- "Probable recursive definition - exceeded maximum depth " +
- maxdepth);
- }
-
- String s = config.getProperty(property);
- if (s == null || s.equals("")) {
- throw new MissingParameterException(property,
- " when evaluating property " + initial);
-// + "\nPossibly incorrect property: " + getSimilarProperty(property));
- }
-
- GroupJep jep = new GroupJep(new Operators());
- jep.setAllowUndeclared(true);
-
- jep.parseExpression(s);
- String[] symbols = getSymbols(jep);
- for (int i = 0; i < symbols.length; i++) {
- Object d = getVal(initial, symbols[i], depth + 1);
- jep.addVariable(symbols[i], d);
- }
- Object ret = jep.getValueAsObject();
- if (jep.hasError())
- System.err.println(jep.getErrorInfo());
- return (Number) ret;
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Returns an array of string, containing the symbols contained in the
- * expression parsed by the specified JEP parser.
- * @param jep
- * the java expression parser containing the list of variables
- * @return an array of strings.
- */
-private String[] getSymbols(org.nfunk.jep.JEP jep)
-{
- Hashtable h = jep.getSymbolTable();
- String[] ret = new String[h.size()];
- Enumeration e = h.keys();
- int i = 0;
- while (e.hasMoreElements()) {
- ret[i++] = (String) e.nextElement();
- }
- return ret;
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads given configuration property. If not found, returns the default
- * value.
- * @param name
- * Name of configuration property
- * @param def
- * default value
- */
-public String getString(String name, String def)
-{
- try {
- return getStr(name);
- } catch (RuntimeException e) {
- manageDefault(name, def, e);
- return def;
- }
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads given configuration property. If not found, throws a
- * MissingParameterException. Removes trailing whitespace characters.
- * @param name
- * Name of configuration property
- */
-public String getString(String name)
-{
- try {
- return getStr(name);
- } catch (RuntimeException e) {
- manageException(name, e);
- return "";
- }
-}
-
-/**
- * The actual method implementing getString().
- */
-private String getStr(String name)
-{
- String result = config.getProperty(name);
- if (result == null) {
- throw new MissingParameterException(name);
-// "\nPossibly incorrect property: " + getSimilarProperty(name));
- }
- debug(name, "" + result);
-
- return result.trim();
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads the given property from the configuration interpreting it as a
- * protocol name. Returns the numeric protocol identifier of this protocol
- * name. See the discussion of protocol name at {@link Configuration} for
- * details on how this numeric id is calculated
- *
- * @param name
- * Name of configuration property
- * @return the numeric protocol identifier associated to the value of the
- * property
- */
-public int getPid(String name)
-{
- try {
- String protname = getStr(name);
- return lookupPid(protname);
- } catch (RuntimeException e) {
- manageException(name, e);
- return 0;
- }
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Calls {@link #getPid(String)}, and returns the default if no property
- * is defined with the given name.
- *
- * @param name
- * Name of configuration property
- * @param pid
- * the default protocol identifier
- * @return the numeric protocol identifier associated to the value of the
- * property, or the default if not defined
- */
-public int getPid(String name, int pid)
-{
- try {
- String protname = getStr(name);
- return lookupPid(protname);
- } catch (RuntimeException e) {
- manageDefault(name, pid, e);
- return pid;
- }
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Returns the numeric protocol identifier of the given protocol name.
- *
- * @param protname
- * the protocol name.
- * @return the numeric protocol identifier associated to the protocol name
- */
-public int lookupPid(String protname)
-{
- Integer ret = protocols.get(protname);
- if (ret == null) {
- throw new MissingParameterException(Configuration.PAR_PROT + "." + protname);
-// "\nPossibly incorrect property: "
-// + getSimilarProperty(PAR_PROT + "." + protname));
- }
- return ret.intValue();
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Returns the name of a protocol that has the given identifier.
- * <p>
- * Note that this is not a constant time operation in the number of
- * protocols, although typically there are very few protocols defined.
- *
- * @param pid
- * numeric protocol identifier.
- * @return name of the protocol that has the given id. null if no protocols
- * have the given id.
- */
-public String lookupPid(int pid)
-{
-
- if (!protocols.containsValue(pid))
- return null;
- for (Map.Entry<String, Integer> i : protocols.entrySet()) {
- if (i.getValue().intValue() == pid)
- return i.getKey();
- }
-
- // never reached but java needs it...
- return null;
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads given configuration property. If not found, throws a
- * {@link MissingParameterException}. When creating the Class object, a
- * few attempts are done to resolve the classname. See
- * {@link Configuration} for details.
- * @param name
- * Name of configuration property
- */
-public Class getClass(String name)
-{
- try {
- return getClazz(name);
- } catch (RuntimeException e) {
- manageException(name, e);
- return null;
- }
-}
-
-private Class getClazz(String name)
-{
- String classname = config.getProperty(name);
- if (classname == null) {
- throw new MissingParameterException(name);
-// "\nPossibly incorrect property: " + getSimilarProperty(name));
- }
- debug(name, classname);
-
- Class c = null;
-
- try {
- // Maybe classname is just a fully-qualified name
- c = Class.forName(classname);
- } catch (ClassNotFoundException e) {
- }
- if (c == null) {
- // Maybe classname is a non-qualified name?
- String fullname = ClassFinder.getQualifiedName(classname);
- if (fullname != null) {
- try {
- c = Class.forName(fullname);
- } catch (ClassNotFoundException e) {
- }
- }
- }
- if (c == null) {
- // Maybe there are multiple classes with the same
- // non-qualified name.
- String fullname = ClassFinder.getQualifiedName(classname);
- if (fullname != null) {
- String[] names = fullname.split(",");
- if (names.length > 1) {
- for (int i = 0; i < names.length; i++) {
- for (int j = i + 1; j < names.length; j++) {
- if (names[i].equals(names[j])) {
- throw new IllegalParameterException(name,
- "The class " + names[i]
- + " appears more than once in the classpath; please check"
- + " your classpath to avoid duplications.");
- }
- }
- }
- throw new IllegalParameterException(name,
- "The non-qualified class name " + classname
- + "corresponds to multiple fully-qualified classes:" + fullname);
- }
- }
- }
- if (c == null) {
- // Last attempt: maybe the fully classified name is wrong,
- // but the classname is correct.
- String shortname = ClassFinder.getShortName(classname);
- String fullname = ClassFinder.getQualifiedName(shortname);
- if (fullname != null) {
- throw new IllegalParameterException(name, "Class "
- + classname + " does not exist. Possible candidate(s): " + fullname);
- }
- }
- if (c == null) {
- throw new IllegalParameterException(name, "Class "
- + classname + " not found");
- }
- return c;
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads given configuration property. If not found, returns the default
- * value.
- * @param name
- * Name of configuration property
- * @param def
- * default value
- * @see #getClass(String)
- */
-public Class getClass(String name, Class def)
-{
-
- try {
- return Configuration.getClass(name);
- } catch (RuntimeException e) {
- manageDefault(name, def, e);
- return def;
- }
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads given configuration property for a class name. It returns an
- * instance of the class. The class must implement a constructor that takes
- * a String as an argument. The value of this string will be <tt>name</tt>.
- * The constructor of the class can see the configuration so it can make
- * use of this name to read its own parameters from it.
- * @param name
- * Name of configuration property
- * @throws MissingParameterException
- * if the given property is not defined
- * @throws IllegalParameterException
- * if there is any problem creating the instance
- */
-public Object getInstance(String name)
-{
- try {
- return getInst(name);
- } catch (RuntimeException e) {
- manageException(name, e);
- return null;
- }
-}
-
-/**
- * The actual method implementing getInstance().
- */
-private Object getInst(String name)
-{
- Class c = getClass(name);
- if (c == null)
- return null;
- final String classname = c.getSimpleName();
-
- try {
- Class pars[] = {String.class};
- Constructor cons = c.getConstructor(pars);
- Object objpars[] = {name};
- return cons.newInstance(objpars);
- } catch (NoSuchMethodException e) {
- throw new IllegalParameterException(name, "Class "
- + classname + " has no " + classname + "(String) constructor");
- } catch (InvocationTargetException e) {
- if (e.getTargetException() instanceof RuntimeException) {
- throw (RuntimeException) e.getTargetException();
- } else {
- e.getTargetException().printStackTrace();
- throw new RuntimeException("" + e.getTargetException());
- }
- } catch (Exception e) {
- throw new IllegalParameterException(name, e + "");
- }
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads given configuration property for a class name. It returns an
- * instance of the class. The class must implement a constructor that takes
- * a String as an argument. The value of this string will be <tt>name</tt>.
- * The constructor of the class can see the configuration so it can make
- * use of this name to read its own parameters from it.
- * @param name
- * Name of configuration property
- * @param def
- * The default object that is returned if there is no property
- * defined with the given name
- * @throws IllegalParameterException
- * if the given name is defined but there is a problem creating
- * the instance.
- */
-public Object getInstance(String name, Object def)
-{
- if (!contains(name))
- return def;
- try {
- return getInst(name);
- } catch (RuntimeException e) {
- manageException(name, e);
- return def;
- }
-}
-
-// -------------------------------------------------------------------
-
-/**
- * It returns an array of class instances. The instances are constructed by
- * calling {@link #getInstance(String)} on the names returned by
- * {@link #getNames(String)}.
- * @param name
- * The component type (i.e. prefix of the list of configuration
- * properties) which will be passed to {@link #getNames(String)}.
- */
-public Object[] getInstanceArray(String name)
-{
-
- String names[] = getNames(name);
- Object[] result = new Object[names.length];
-
- for (int i = 0; i < names.length; ++i) {
- result[i] = getInstance(names[i]);
- }
-
- return result;
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Returns an array of names prefixed by the specified name. The array is
- * sorted as follows. If there is no config entry
- * <code>{@value peersim.config.Configuration#PAR_INCLUDE}+"."+name</code> or
- * <code>{@value peersim.config.Configuration#PAR_ORDER}+"."+name</code> then the order is
- * alphabetical. Otherwise this entry defines the order. For more
- * information see {@link Configuration}.
- * @param name
- * the component type (i.e., the prefix)
- * @return the full property names in the order specified by the
- * configuration
- */
-public String[] getNames(String name)
-{
- ArrayList<String> ll = new ArrayList<String>();
- final String pref = name + ".";
-
- Enumeration e = config.propertyNames();
- while (e.hasMoreElements()) {
- String key = (String) e.nextElement();
- if (key.startsWith(pref) && key.indexOf(".", pref.length()) < 0)
- ll.add(key);
- }
- String[] ret = ll.toArray(new String[ll.size()]);
- return order(ret, name);
-}
-
-// -------------------------------------------------------------------
-
-/**
- * The input of this method is a set of property <code>names</code> (e.g.
- * initializers, controls and protocols) and a string specifying the type
- * (prefix) of these. The output is in <code>names</code>, which will
- * contain a permutation of the original array. Parameter
- * PAR_INCLUDE+"."+type, or if not present, PAR_ORDER+"."+type is read from
- * the configuration. If none of them are defined then the order is
- * identical to that of <code>names</code>. Otherwise the configuration
- * entry must contain entries from <code>names</code>. It is assumed
- * that the entries in <code>names</code> contain only word characters
- * (alphanumeric and underscore '_'. The order configuration entry thus
- * contains a list of entries from <code>names</code> separated by any
- * non-word characters.
- * <p>
- * It is not required that all entries are listed. If PAR_INCLUDE is used,
- * then only those entries are returned that are listed. If PAR_ORDER is
- * used, then all names are returned, but the array will start with those
- * that are listed. The rest of the names follow in alphabetical order.
- *
- *
- * @param names
- * the set of property names to be searched
- * @param type
- * the string identifying the particular set of properties to be
- * inspected
- */
-private String[] order(String[] names, String type)
-{
- String order = getString(Configuration.PAR_INCLUDE + "." + type, null);
- boolean include = order != null;
- if (!include)
- order = getString(Configuration.PAR_ORDER + "." + type, null);
-
- int i = 0;
- if (order != null && !order.equals("")) {
- // split around non-word characters
- String[] sret = order.split("\\W+");
- for (; i < sret.length; i++) {
- int j = i;
- for (; j < names.length; ++j)
- if (names[j].equals(type + "." + sret[i]))
- break;
- if (j == names.length) {
- throw new IllegalParameterException(
- (include ? Configuration.PAR_INCLUDE : Configuration.PAR_ORDER)
- + "." + type, type + "." + sret[i] + " is not defined.");
- } else // swap the element to current position
- {
- String tmps = names[j];
- names[j] = names[i];
- names[i] = tmps;
- }
- }
- }
-
- Arrays.sort(names, i, names.length);
- int retsize = (include ? i : names.length);
- String[] ret = new String[retsize];
- for (int j = 0; j < retsize; ++j)
- ret[j] = names[j];
- return ret;
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Print debug information for configuration. The amount of information
- * depends on the debug level DEBUG. 0 = nothing 1 = just the config name 2 =
- * config name plus method calling
- *
- * @param name
- */
-private void debug(String name, String result)
-{
- if (debugLevel == DEBUG_NO)
- return;
- StringBuffer buffer = new StringBuffer();
- buffer.append("DEBUG ");
- buffer.append(name);
- buffer.append(" = ");
- buffer.append(result);
-
- // Additional info
- if (debugLevel == DEBUG_CONTEXT) {
-
- buffer.append("\n at ");
- // Obtain the stack trace
- StackTraceElement[] stack = null;
- try {
- throw new Exception();
- } catch (Exception e) {
- stack = e.getStackTrace();
- }
-
- // Search the element that invoked Configuration
- // It's the first whose class is different from Configuration
- int pos;
- for (pos = 0; pos < stack.length; pos++) {
- if (!stack[pos].getClassName().equals(Configuration.class.getName()))
- break;
- }
-
- buffer.append(stack[pos].getClassName());
- buffer.append(":");
- buffer.append(stack[pos].getLineNumber());
- buffer.append(", method ");
- buffer.append(stack[pos - 1].getMethodName());
- buffer.append("()");
- }
-
- System.err.println(buffer);
-}
-
-// -------------------------------------------------------------------
-
-/**
- * @return an array of adjacent letter pairs contained in the input string
- * http://www.catalysoft.com/articles/StrikeAMatch.html
- */
-private String[] letterPairs(String str)
-{
- int numPairs = str.length() - 1;
- String[] pairs = new String[numPairs];
- for (int i = 0; i < numPairs; i++) {
- pairs[i] = str.substring(i, i + 2);
- }
- return pairs;
-}
-
-// -------------------------------------------------------------------
-
-/**
- * @return an ArrayList of 2-character Strings.
- * http://www.catalysoft.com/articles/StrikeAMatch.html
- */
-private ArrayList<String> wordLetterPairs(String str)
-{
- ArrayList<String> allPairs = new ArrayList<String>();
- // Tokenize the string and put the tokens/words into an array
- String[] words = str.split("\\s");
- // For each word
- for (int w = 0; w < words.length; w++) {
- // Find the pairs of characters
- String[] pairsInWord = letterPairs(words[w]);
- for (int p = 0; p < pairsInWord.length; p++) {
- allPairs.add(pairsInWord[p]);
- }
- }
- return allPairs;
-}
-
-// -------------------------------------------------------------------
-
-/**
- * @return lexical similarity value in the range [0,1]
- * http://www.catalysoft.com/articles/StrikeAMatch.html
- */
-private double compareStrings(String str1, String str2)
-{
- ArrayList pairs1 = wordLetterPairs(str1.toUpperCase());
- ArrayList pairs2 = wordLetterPairs(str2.toUpperCase());
- int intersection = 0;
- int union_ = pairs1.size() + pairs2.size();
- for (int i = 0; i < pairs1.size(); i++) {
- Object pair1 = pairs1.get(i);
- for (int j = 0; j < pairs2.size(); j++) {
- Object pair2 = pairs2.get(j);
- if (pair1.equals(pair2)) {
- intersection++;
- pairs2.remove(j);
- break;
- }
- }
- }
- return (2.0 * intersection) / union_;
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Among the defined properties, returns the one more similar to String
- * property
- */
-private String getSimilarProperty(String property)
-{
- String bestProperty = null;
- double bestValue = 0.0;
- Enumeration e = config.keys();
- while (e.hasMoreElements()) {
- String key = (String) e.nextElement();
- double compare = compareStrings(key, property);
- if (compare > bestValue) {
- bestValue = compare;
- bestProperty = key;
- }
- }
- return bestProperty;
-}
-
-//-------------------------------------------------------------------
-
-private void manageDefault(String name, Object def,
- RuntimeException e)
-{
- debug(name, "" + def + " (DEFAULT)");
- if (check) {
- System.out.println("Warning: Property " + name + " = " +
- def + " (DEFAULT)");
- }
- if (e instanceof MissingParameterException) {
- // Do nothing
- } else {
- manageException(name, e);
- }
-}
-
-//-------------------------------------------------------------------
-
-private void manageException(String name, RuntimeException e)
-{
- if (check) {
- if (e instanceof MissingParameterException) {
- // Print just the short message in this case
- System.out.println("Error: " +
- ((MissingParameterException) e).getShortMessage());
- } else if (e instanceof IllegalParameterException) {
- // Print just the short message in this case
- System.out.println("Error: " +
- ((IllegalParameterException) e).getShortMessage());
- } else {
- System.out.println("Error: " + e.getMessage());
- }
- } else {
- throw e;
- }
-}
-
-//-------------------------------------------------------------------
-
-}
+++ /dev/null
-/*
- * 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.config;
-
-import java.util.Properties;
-import java.io.*;
-
-/**
-* Class for handling configuration files. Extends the functionality
-* of Properties by handling files, system resources and command lines.
-*/
-public class ConfigProperties extends Properties {
-
-
-// =========== Public Constructors ===================================
-// ===================================================================
-
-
-/**
-* Calls super constructor.
-*/
-public ConfigProperties() { super(); }
-
-// -------------------------------------------------------------------
-
-/**
-* Constructs a ConfigProperty object from a parameter list.
-* The algorithm is as follows: first <code>resource</code> is used to attempt
-* loading default values from the given system resource.
-* Then all Strings in <code>pars</code> are processed in the order they
-* appear in the array. For <code>pars[i]</code>, first a property file
-* with the name <code>pars[i]</code> is attempted to be loaded. If the file
-* does not exist or loading produces any other IOException, <code>pars[i]</code>
-* is interpreted as a property definition, and it is set.
-* <p>
-* A little inconvenience is that if <code>pars[i]</code> is supposed to be
-* a command line argument, but it is a valid filename at the same time by
-* accident, the algorithm will process it as a file instead of a command line
-* argument. The caller must take care of that.
-* <p>
-* No exceptions are thrown, instead error messages are written to the
-* standard error. Users who want a finer control should use
-* the public methods of this class.
-*
-* @param pars The (probably command line) parameter list.
-* @param resource The name of the system resource that contains the
-* defaults. null if there isn't any.
-*
-*/
-public ConfigProperties( String[] pars, String resource ) {
-
- try
- {
- if( resource != null )
- {
- loadSystemResource(resource);
- System.err.println("ConfigProperties: System resource "
- +resource+" loaded.");
- }
- }
- catch( Exception e )
- {
- System.err.println("ConfigProperties: " + e );
- }
-
- if( pars == null || pars.length == 0 ) return;
-
- for (int i=0; i < pars.length; i++)
- {
- try
- {
- load( pars[i] );
- System.err.println(
- "ConfigProperties: File "+pars[i]+" loaded.");
- pars[i] = "";
- }
- catch( IOException e )
- {
- try
- {
- loadPropertyString( pars[i] );
- System.err.println("ConfigProperties: Property '" +
- pars[i] + "' set.");
- }
- catch( Exception e2 )
- {
- System.err.println("ConfigProperties: " + e2 );
- }
- }
- catch( Exception e )
- {
- System.err.println("ConfigProperties: " + e );
- }
- }
-}
-
-// -------------------------------------------------------------------
-
-/**
-* Constructs a ConfigProperty object by loading a file by calling
-* {@link #load}.
-* @param fileName The name of the configuration file.
-*/
-public ConfigProperties( String fileName ) throws IOException {
-
- load( fileName );
-}
-
-// -------------------------------------------------------------------
-
-/**
-* Calls super constructor.
-*/
-public ConfigProperties( Properties props ) {
-
- super( props );
-}
-
-// -------------------------------------------------------------------
-
-/**
-* Calls {@link #ConfigProperties(String[],String)} with resource set to null.
-*/
-public ConfigProperties( String[] pars ) {
-
- this( pars, null );
-}
-
-
-// =========== Public methods ========================================
-// ===================================================================
-
-
-/**
-* Loads given file. Calls <code>Properties.load</code> with a file
-* input stream to the given file.
-*/
-public void load( String fileName ) throws IOException {
-
- FileInputStream fis = new FileInputStream( fileName );
- load( fis );
- fis.close();
-}
-
-// -------------------------------------------------------------------
-
-/**
-* Adds the properties from the given property file. Searches in the class path
-* for the file with the given name.
-*/
-public void loadSystemResource( String n ) throws IOException {
-
- ClassLoader cl = getClass().getClassLoader();
- load( cl.getResourceAsStream( n ) );
-}
-
-// -------------------------------------------------------------------
-
-/**
-* Appends a property defined in the given string.
-* The string is considered as a property file line.
-* It is converted to a byte array according to the
-* default character encoding and then loaded by the
-* <code>Properties.load</code> method. This means that the ISO-8859-1
-* (or compatible) encoding is assumed.
-*/
-public void loadPropertyString( String prop ) throws IOException {
-
- StringBuffer sb = new StringBuffer();
- sb.append( prop ).append( "\n" );
- load( new ByteArrayInputStream(sb.toString().getBytes()) );
-}
-}
-
+++ /dev/null
-/*
- * 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.config;
-
-import java.util.*;
-
-/**
- * Fully static class to store configuration information. It defines a
- * method, {@link #setConfig(Properties)}, to set configuration data. This
- * method is called by the simulator engines as the very first thing they
- * do. It can be called only once, after that the class becomes read only.
- * All components can then access this configuration and utility methods to
- * read property values based on their names.
- * <p>
- * The design of this class also hides the actual implementation of the
- * configuration which can be Properties, XML, whatever. Currently only
- * Properties is supported.
- * <p>
- * Apart from storing (name,value) pairs, this class also does some
- * processing, and offers some utility functions. This extended
- * functionality consists of the following: reading values with type
- * checking, ordering of entries, pre-processing protocol names, parsing
- * expressions, resolving underspecified classnames, and finally some basic
- * debugging possibilities. We discuss these in the following.
- * <p>
- * Note that the configuration is initialized using a Properties object.
- * The class of this object might implement some additional pre-processing
- * on the file or provide an extended syntax for defining property files.
- * See {@link ParsedProperties} for more details. This is the class that is
- * currently used by simulation engines.
- * <h3>Typed reading of values</h3>
- * Properties can have arbitrary values of type String. This class offers a
- * set of read methods that perform the appropriate conversion of the
- * string value to the given type, eg long. They also allow for specifying
- * default values in case the given property is not specified.
- * <h3>Resolving class names</h3>
- *
- * The possibilities for the typed reading of a value includes interpreting
- * the value as a class name. In this case an object will be constructed.
- * It is described at method {@link #getInstance(String)} how this is
- * achieved exactly. What needs to be noted here is that the property value
- * need not be a fully specified classname. It might contain only the short
- * class name without the package specification. In this case, it is
- * attempted to locate a class with that name in the classpath, and if a
- * unique class is found, it will be used. This simplifies the
- * configuration files and also allows to remove their dependence on the
- * exact location of the class.
- *
- * <h3>Components and their ordering</h3>
- * The idea of the configuration is that it mostly contains components and
- * their descriptions (parameters). Although this class is blind to the
- * semantics of these components, it offers some low level functionality
- * that helps dealing with them. This functionality is based on the
- * assumption that components have a type and a name. Both types and names
- * are strings of alphanumeric and underscore characters. For example,
- * {@value #PAR_PROT} is a type, "foo" can be a name. Method
- * {@link #getNames} allow the caller to get the list of names for a given
- * type. Some other methods, like {@link #getInstanceArray} use this list
- * to return a list of components.
- *
- * <p>
- * Assuming the configuration is in Properties format (which is currently
- * the only format available) component types and names are defined as
- * follows. Property names containing two non-empty words separated by one
- * dot (".") character are treated specially (the words contain word
- * characters: alphanumeric and underscore ("_")). The first word will be
- * the type, and the second is the name of a component. For example,
- *
- * <pre>
- * control.conn ConnectivityObserver
- * control.1 WireKOut
- * control.2 PrintGraph
- * </pre>
- *
- * defines control components of names "conn","1" an "2" (arguments of the
- * components not shown). When {@link #getNames} or
- * {@link #getInstanceArray} are called, eg
- * <code>getNames("control")</code>, then the order in which these are
- * returned is alphabetical:
- * <code>["control.1","control.2","control.conn"]</code>. If you are not
- * satisfied with lexicographic order, you can specify the order in this
- * way.
- *
- * <pre>
- * order.control 1,conn,2
- * </pre>
- *
- * where the names are separated by any non-word character (non
- * alphanumeric or underscore). If not all names are listed then the given
- * order is followed by alphabetical order of the rest of the items, e.g.
- *
- * <pre>
- * order.control 2
- * </pre>
- *
- * results in <code>["control.2","control.1","control.conn"]</code>.
- * <p>
- * It is also possible to exclude elements from the list, while ordering
- * them. The syntax is identical to that of the above, only the parameter
- * name begins with <code>include</code>. For example
- *
- * <pre>
- * include.control conn 2
- * </pre>
- *
- * will result in returning <em>only</em> <code>control.conn</code> and
- * <code>control.2</code>, in this order. Note that for example the
- * empty list results in a zero length array in this case.
- * <em>Important!</em> If include is defined then ordering is ignored.
- * That is, include is stronger than order.
- * <h3>Protocol names</h3>
- * As mentioned, the configuration is generally blind to the actual names
- * of the components. There is an exception: the components of type
- * {@value #PAR_PROT}. These are pre-processed a bit to enhance
- * performance: protocol names are mapped to numeric protocol identifiers.
- * The numeric identifier of a protocol is its index in the array returned
- * by {@link #getNames}. See above how to control this order. The numeric
- * identifiers then can be looked up based on the name and vice versa.
- * Besides, the identifier can be directly requested based on a property
- * name when the protocol name is the value of a property which is
- * frequently the case.
- * <p>
- * <h3>Expressions</h3>
- * Numeric property values can be complex expressions, that are parsed
- * using <a href="http://www.singularsys.com/jep/">JEP</a>. You can write
- * expression using the syntax that you can find <a
- * href="http://www.singularsys.com/jep/doc/html/op_and_func.html"> here</a>.
- * For example,
- *
- * <pre>
- * MAG 2
- * SIZE 2ˆMAG
- * </pre>
- *
- * SIZE=4. You can also have complex expression trees like this:
- *
- * <pre>
- * A B+C
- * B D+E
- * C E+F
- * D 1
- * E F
- * F 2
- * </pre>
- *
- * that results in A=7, B=3, C=4, D=1, E=2, F=2
- *
- * <p>
- * Expressions like "sub-expression op sub-expression" are computed based
- * on the type of the sub-expressions. If both sub-expressions are integer,
- * the computation is done using integer arithmetics and the result is an
- * integer. So, for example, 5/2 returns 2. If one of the sub-expression is
- * floating point, the computation is based on floating-point arithmetics
- * (double precision) and the result is a floating point value. So, for
- * example, 5.0/2 returns 2.5.
- *
- * <p>
- * Expressions are parsed recursively. Note that no optimization is done,
- * so expression F is evaluated three times here (due to the fact that
- * appears twice in C and once in B). But since properties are read just
- * once at initialization, this is not a performance problem.
- *
- * <p>
- * Finally, recursive definitions are not allowed (and without function
- * definitions, they make no sense). Since it is difficult to discover
- * complex recursive chains, a simple trick is used: if the depth of
- * recursion is greater than a given threshold (configurable, currently
- * {@value #DEFAULT_MAXDEPTH}, an error message is printed. This avoids to
- * fill the stack, that results in an anonymous OutOfMemoryError. So, if
- * you write
- *
- * <pre>
- * overlay.size SIZE
- * SIZE SIZE-1
- * </pre>
- *
- * you get an error message: Parameter "overlay.size": Probable recursive
- * definition - exceeded maximum depth {@value #DEFAULT_MAXDEPTH}
- *
- * <h3>Debug</h3>
- *
- * It is possible to obtain debug information about the configuration
- * properties by activating special configuration properties.
- * <p>
- * If property {@value #PAR_DEBUG} is defined, each config property and the
- * associated value are printed. Properties that are not present in the
- * config file but have default values are postfixed with the string
- * "(DEFAULT)".
- * <p>
- * If property {@value #PAR_DEBUG} is defined and it is equal to
- * {@value #DEBUG_EXTENDED}, information about the configuration method
- * invoked, and where this method is invoked, is also printed. If it is
- * equal to {@value #DEBUG_FULL}, all the properties are printed, even if
- * they are not read.
- * <p>
- * Each line printed by this debug feature is prefixed by the string
- * "DEBUG".
- *
- * <h3>Use of brackets</h3>
- *
- * For the sake of completeness, we mention it here that if this class is
- * initialized using {@link ParsedProperties}, then it is possible to use
- * some more compressed format to specify the components. See
- * {@link ParsedProperties#load}.
- *
- */
-public class Configuration
-{
-
-// =================== static fields =================================
-// ===================================================================
-
-/** Default max depth limit to avoid recursive definitions */
-public static final int DEFAULT_MAXDEPTH = 100;
-
-/**
- * The debug level for the configuration. If defined, a line is printed for
- * each configuration parameter read. If defined and equal to
- * {@value #DEBUG_EXTENDED}, additional context information for debug is
- * printed. If defined and equal to {@value #DEBUG_FULL}, all the
- * configuration properties are printed at the beginning, not just when
- * they are called.
- * @config
- */
-static final String PAR_DEBUG = "debug.config";
-
-/**
- * If parameter {@value #PAR_DEBUG} is equal to this string, additional
- * context information for debug is printed.
- */
-static final String DEBUG_EXTENDED = "context";
-
-/**
- * If parameter {value #PAR_DEBUG} is equal to this string, all the
- * configuration properties are printed at the beginning, not just when
- * they are called.
- */
-static final String DEBUG_FULL = "full";
-
-/**
- * The maximum depth for expressions. This is a simple mechanism to avoid
- * unbounded recursion. The default is {@value #DEFAULT_MAXDEPTH}, and you
- * probably don't want to change it.
- * @config
- */
-static final String PAR_MAXDEPTH = "expressions.maxdepth";
-
-/**
- * Used to configure ordering of the components. Determines the ordering in
- * the array as returned by {@link #getNames}. See the general description
- * of {@link Configuration} for details.
- * @config
- */
-static final String PAR_ORDER = "order";
-
-/**
- * Used to configure ordering of the components. Determines the ordering in
- * the array as returned by {@link #getNames}, and can bu used to also
- * exclude elements. See the general description of {@link Configuration}
- * for details.
- * @config
- */
-static final String PAR_INCLUDE = "include";
-
-// XXX it's ugly because it replicates the definition of Node.PAR_PROT, but
-// this would be the only dependence on the rest of the core...
-/**
- * The type name of components describing protocols. This is the only point
- * at which the class is not blind to the actual semantics of the
- * configuration.
- */
-static final String PAR_PROT = "protocol";
-
-/**
- * The properties object that stores all configuration information.
- */
-private static ConfigContainer config = null;
-
-// =================== initialization ================================
-// ===================================================================
-
-/** to prevent construction */
-private Configuration()
-{
-}
-
-// =================== static public methods =========================
-// ===================================================================
-
-/**
- * Sets the system-wide configuration in Properties format. It can be
- * called only once. After that the configuration becomes unmodifiable
- * (read only). If modification is attempted, a RuntimeException is thrown
- * and no change is made.
- * @param p
- * The Properties object containing configuration info
- */
-public static void setConfig(Properties p)
-{
- if (config != null) {
- throw new RuntimeException("Setting configuration was attempted twice.");
- }
- config = new ConfigContainer(p, false);
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Sets the system-wide configuration in Properties format. It can be
- * called only once. After that the configuration becomes unmodifiable
- * (read only). If modification is attempted, a RuntimeException is thrown
- * and no change is made.
- * @param p
- * The Properties object containing configuration info
- */
-public static void setConfig(Properties p, boolean check)
-{
- if (config != null) {
- throw new RuntimeException("Setting configuration was attempted twice.");
- }
- config = new ConfigContainer(p, check);
-}
-
-// -------------------------------------------------------------------
-
-/**
- * @return true if and only if name is a specified (existing) property.
- */
-public static boolean contains(String name)
-{
- return config.contains(name);
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads given configuration property. If not found, throws a
- * {@link MissingParameterException}.
- * @param name
- * Name of configuration property
- * @param def
- * default value
- */
-public static boolean getBoolean(String name, boolean def)
-{
- return config.getBoolean(name, def);
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads given property. If not found, or the value is empty string then
- * throws a {@link MissingParameterException}. Empty string is not
- * accepted as false due to the similar function of {@link #contains} which
- * returns true in that case. True is returned if the lowercase value of
- * the property is "true", otherwise false is returned.
- * @param name
- * Name of configuration property
- */
-public static boolean getBoolean(String name)
-{
- return config.getBoolean(name);
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads given configuration property. If not found, returns the default
- * value.
- * @param name
- * Name of configuration property
- * @param def
- * default value
- */
-public static int getInt(String name, int def)
-{
- return config.getInt(name, def);
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads given configuration property. If not found, throws a
- * {@link MissingParameterException}.
- * @param name
- * Name of configuration property
- */
-public static int getInt(String name)
-{
- return config.getInt(name);
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads given configuration property. If not found, returns the default
- * value.
- * @param name
- * Name of configuration property
- * @param def
- * default value
- */
-public static long getLong(String name, long def)
-{
- return config.getLong(name, def);
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads given configuration property. If not found, throws a
- * {@link MissingParameterException}.
- * @param name
- * Name of configuration property
- */
-public static long getLong(String name)
-{
- return config.getLong(name);
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads given configuration property. If not found, returns the default
- * value.
- * @param name
- * Name of configuration property
- * @param def
- * default value
- */
-public static double getDouble(String name, double def)
-{
- return config.getDouble(name, def);
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads given configuration property. If not found, throws a
- * MissingParameterException.
- * @param name
- * Name of configuration property
- */
-public static double getDouble(String name)
-{
- return config.getDouble(name);
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads given configuration property. If not found, returns the default
- * value.
- * @param name
- * Name of configuration property
- * @param def
- * default value
- */
-public static String getString(String name, String def)
-{
- return config.getString(name, def);
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads given configuration property. If not found, throws a
- * MissingParameterException. Removes trailing whitespace characters.
- * @param name
- * Name of configuration property
- */
-public static String getString(String name)
-{
- return config.getString(name);
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads the given property from the configuration interpreting it as a
- * protocol name. Returns the numeric protocol identifier of this protocol
- * name. See the discussion of protocol name at {@link Configuration} for
- * details on how this numeric id is calculated
- *
- * @param name
- * Name of configuration property
- * @return the numeric protocol identifier associated to the value of the
- * property
- */
-public static int getPid(String name)
-{
- return config.getPid(name);
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Calls {@link #getPid(String)}, and returns the default if no property
- * is defined with the given name.
- *
- * @param name
- * Name of configuration property
- * @param pid
- * the default protocol identifier
- * @return the numeric protocol identifier associated to the value of the
- * property, or the default if not defined
- */
-public static int getPid(String name, int pid)
-{
- return config.getPid(name, pid);
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Returns the numeric protocol identifier of the given protocol name.
- *
- * @param protname
- * the protocol name.
- * @return the numeric protocol identifier associated to the protocol name
- */
-public static int lookupPid(String protname)
-{
- return config.lookupPid(protname);
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Returns the name of a protocol that has the given identifier.
- * <p>
- * Note that this is not a constant time operation in the number of
- * protocols, although typically there are very few protocols defined.
- *
- * @param pid
- * numeric protocol identifier.
- * @return name of the protocol that has the given id. null if no protocols
- * have the given id.
- */
-public static String lookupPid(int pid)
-{
- return config.lookupPid(pid);
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads given configuration property. If not found, throws a
- * {@link MissingParameterException}. When creating the Class object, a
- * few attempts are done to resolve the classname. See
- * {@link Configuration} for details.
- * @param name
- * Name of configuration property
- */
-public static Class getClass(String name)
-{
- return config.getClass(name);
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads given configuration property. If not found, returns the default
- * value.
- * @param name
- * Name of configuration property
- * @param def
- * default value
- * @see #getClass(String)
- */
-public static Class getClass(String name, Class def)
-{
- return config.getClass(name, def);
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads given configuration property for a class name. It returns an
- * instance of the class. The class must implement a constructor that takes
- * a String as an argument. The value of this string will be <tt>name</tt>.
- * The constructor of the class can see the configuration so it can make
- * use of this name to read its own parameters from it.
- * @param name
- * Name of configuration property
- * @throws MissingParameterException
- * if the given property is not defined
- * @throws IllegalParameterException
- * if there is any problem creating the instance
- */
-public static Object getInstance(String name)
-{
- return config.getInstance(name);
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Reads given configuration property for a class name. It returns an
- * instance of the class. The class must implement a constructor that takes
- * a String as an argument. The value of this string will be <tt>name</tt>.
- * The constructor of the class can see the configuration so it can make
- * use of this name to read its own parameters from it.
- * @param name
- * Name of configuration property
- * @param def
- * The default object that is returned if there is no property
- * defined with the given name
- * @throws IllegalParameterException
- * if the given name is defined but there is a problem creating
- * the instance.
- */
-public static Object getInstance(String name, Object def)
-{
- return config.getInstance(name, def);
-}
-
-// -------------------------------------------------------------------
-
-/**
- * It returns an array of class instances. The instances are constructed by
- * calling {@link #getInstance(String)} on the names returned by
- * {@link #getNames(String)}.
- * @param name
- * The component type (i.e. prefix of the list of configuration
- * properties) which will be passed to {@link #getNames(String)}.
- */
-public static Object[] getInstanceArray(String name)
-{
- return config.getInstanceArray(name);
-}
-
-// -------------------------------------------------------------------
-
-/**
- * Returns an array of names prefixed by the specified name. The array is
- * sorted as follows. If there is no config entry
- * <code>{@value #PAR_INCLUDE}+"."+name</code> or
- * <code>{@value #PAR_ORDER}+"."+name</code> then the order is
- * alphabetical. Otherwise this entry defines the order. For more
- * information see {@link Configuration}.
- * @param name
- * the component type (i.e., the prefix)
- * @return the full property names in the order specified by the
- * configuration
- */
-public static String[] getNames(String name)
-{
- return config.getNames(name);
-}
-
-}
+++ /dev/null
-/*
- * 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.config;
-
-/**
- * Reads configuration regarding relations between protocols.
- *
- * Technically, this class is not necessary because protocols could
- * access the configuration directly. However, it provides much faster
- * access to "linkable" and "transport" information, enhancing runtime speed.
- *
- * This class is a static singleton and is initialized only when first accessed.
- * During initialization it reads and caches the configuration info it handles.
- */
-public class FastConfig
-{
-
-// ======================= fields ===========================================
-// ===========================================================================
-
-/**
- * Parameter name in configuration that attaches a linkable protocol to a
- * protocol. The property can contain multiple protocol names, in one line,
- * separated by non-word characters (e.g. whitespace or ",").
- * @config
- */
-private static final String PAR_LINKABLE = "linkable";
-
-/**
- * Parameter name in configuration that attaches a transport layer protocol to a
- * protocol.
- * @config
- */
-private static final String PAR_TRANSPORT = "transport";
-
-/**
- * This array stores the protocol ids of the {@link peersim.core.Linkable}
- * protocols that are linked to the protocol given by the array index.
- */
-protected static final int[][] links;
-
-/**
- * This array stores the protocol id of the {@link peersim.transport.Transport}
- * protocol that is linked to the protocol given by the array index.
- */
-protected static final int[] transports;
-
-
-// ======================= initialization ===================================
-// ==========================================================================
-
-
-/**
- * This static initialization block reads the configuration for information that
- * it understands. Currently it understands property {@value #PAR_LINKABLE}
- * and {@value #PAR_TRANSPORT}.
- *
- * Protocols' linkable and transport definitions are prefetched
- * and stored in arrays, to enable fast access during simulation.
- *
- * Note that this class does not perform any type checks. The purpose of the
- * class is purely to speed up access to linkable and transport information,
- * by providing a fast alternative to reading directly from the
- * <code>Configuration</code> class.
- */
-static {
- String[] names = Configuration.getNames(Configuration.PAR_PROT);
- links = new int[names.length][];
- transports = new int[names.length];
- for (int i = 0; i < names.length; ++i)
- {
- if (Configuration.contains(names[i] + "." + PAR_LINKABLE))
- {
- // get string of linkables
- String str = Configuration.getString(names[i] + "." + PAR_LINKABLE);
- // split around non-word characters
- String[] linkNames = str.split("\\W+");
- links[i] = new int[linkNames.length];
- for (int j=0; j<linkNames.length; ++j)
- links[i][j] = Configuration.lookupPid(linkNames[j]);
- }
- else
- links[i] = new int[0]; // empty set
-
- if (Configuration.contains(names[i] + "." + PAR_TRANSPORT))
- transports[i] =
- Configuration.getPid(names[i] + "." + PAR_TRANSPORT);
- else
- transports[i] = -1;
- }
-}
-
-// ---------------------------------------------------------------------
-
-/** to prevent construction */
-private FastConfig() {}
-
-// ======================= methods ==========================================
-// ==========================================================================
-
-
-/**
- * Returns true if the given protocol has at least one linkable protocol
- * associated with it, otherwise false.
- */
-public static boolean hasLinkable(int pid) { return numLinkables(pid) > 0; }
-
-// ---------------------------------------------------------------------
-
-/**
- * Returns the number of linkable protocols associated with a given protocol.
- */
-public static int numLinkables(int pid) { return links[pid].length; }
-
-// ---------------------------------------------------------------------
-
-/**
- * Returns the protocol id of the <code>linkIndex</code>-th linkable used by
- * the protocol identified by pid. Throws an
- * IllegalParameterException if there is no linkable associated with the given
- * protocol: we assume here that this happens when the configuration is
- * incorrect.
- */
-public static int getLinkable(int pid, int linkIndex)
-{
- if (linkIndex >= numLinkables(pid)) {
- String[] names = Configuration.getNames(Configuration.PAR_PROT);
- throw new IllegalParameterException(names[pid],
- "Protocol " + pid + " has no "+PAR_LINKABLE+
- " parameter with index" + linkIndex);
- }
- return links[pid][linkIndex];
-}
-
-//---------------------------------------------------------------------
-
-/**
- * Invokes <code>getLinkable(pid, 0)</code>.
- */
-public static int getLinkable(int pid)
-{
- return getLinkable(pid, 0);
-}
-
-// ---------------------------------------------------------------------
-
-/**
- * Returns true if the given protocol has a transport protocol associated with
- * it, otherwise false.
- */
-public static boolean hasTransport(int pid)
-{
- return transports[pid] >= 0;
-}
-
-// ---------------------------------------------------------------------
-
-/**
- * Returns the id of the transport protocol used by the protocol identified
- * by pid.
- * Throws an IllegalParameterException if there is no transport associated
- * with the given protocol: we assume here that his happens when the
- * configuration is incorrect.
- */
-public static int getTransport(int pid)
-{
- if (transports[pid] < 0) {
- String[] names = Configuration.getNames(Configuration.PAR_PROT);
- throw new IllegalParameterException(names[pid],
- "Protocol " + pid + " has no "+PAR_TRANSPORT + " parameter");
- }
- return transports[pid];
-}
-
-}
+++ /dev/null
-/*
- * 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.config;
-
-/**
-* Exception thrown to indicate that a
-* configuration property has an invalid value. It is thrown by
-* several methods in {@link Configuration} and can be thrown by any
-* component that reads the configuration.
-*/
-public class IllegalParameterException extends RuntimeException {
-
-// ================== initialization =====================================
-// =======================================================================
-
-/**
-* Calls super constructor. It passes a string message which is the given
-* message, prefixed with the given property name.
-* @param name Name of configuration property that is invalid
-* @param message Additional info about why the value is invalid
-*/
-public IllegalParameterException(String name, String message) {
-
- super("Parameter \"" + name + "\": " + message);
-}
-
-// ================== methods ============================================
-// =======================================================================
-
-/**
-* Extends message with info from stack trace.
-* It tries to guess what class called {@link Configuration} and
-* adds relevant info from the stack trace about it to the message.
-*/
-public String getMessage() {
-
- StackTraceElement[] stack = getStackTrace();
-
- // Search the element that invoked Configuration
- // It's the first whose class is different from Configuration
- int pos;
- for (pos=0; pos < stack.length; pos++)
- {
- if (!stack[pos].getClassName().equals(
- Configuration.class.getName()))
- break;
- }
-
- return super.getMessage()+"\nAt "+
- getStackTrace()[pos].getClassName()+"."+
- getStackTrace()[pos].getMethodName()+":"+
- getStackTrace()[pos].getLineNumber();
-}
-
-/**
- * Returns the exception message without stack trace information
- */
-public String getShortMessage()
-{
- return super.getMessage();
-}
-
-}
-
+++ /dev/null
-/*
- * 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.config;
-
-/**
-* Exception thrown to indicate that a
-* configuration property is not defined. It is thrown exclusively by
-* {@link Configuration}, since it is the only class that has access to the
-* set of defined properties.
- */
-public class MissingParameterException extends RuntimeException {
-
-// ================== initialization =====================================
-// =======================================================================
-
-MissingParameterException(String name) {
-
- super("Parameter \"" + name + "\" not found.");
-}
-
-MissingParameterException(String name, String motivation) {
-
- super("Parameter \"" + name + "\" not found " + motivation);
-}
-
-// ================== methods ============================================
-// =======================================================================
-
-/**
-* Extends message with info from stack trace.
-* It tries to guess what class called {@link Configuration} and
-* adds relevant info from the stack trace about it to the message.
-*/
-public String getMessage() {
-
- StackTraceElement[] stack = getStackTrace();
-
- // Search the element that invoked Configuration
- // It's the first whose class is different from Configuration
- int pos;
- for (pos=0; pos < stack.length; pos++) {
- if (!stack[pos].getClassName().equals(
- Configuration.class.getName()))
- break;
- }
-
- return super.getMessage()+"\nAt "+
- getStackTrace()[pos].getClassName()+"."+
- getStackTrace()[pos].getMethodName()+":"+
- getStackTrace()[pos].getLineNumber();
-}
-
-/**
- * Returns the exception message without stack trace information
- */
-public String getShortMessage()
-{
- return super.getMessage();
-}
-
-}
+++ /dev/null
-/*
- * 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.config;
-
-import java.io.*;
-
-/**
- * A subclass of PrintStream whose methods ignore the content
- * being written.
- *
- * @author Alberto Montresor
- * @version $Revision: 1.1 $
- */
-public class NullPrintStream extends PrintStream
-{
-
-/**
- * Creates a null print stream that does not print anything.
- */
-public NullPrintStream()
-{
- super(System.out);
-}
-
-/**
- * This methods does not print anything.
- */
-public synchronized void write(byte[] b, int off, int len)
-{
-}
-
-/**
- * This methods does not print anything.
- */
-public synchronized void write(int b)
-{
-}
-
-/**
- * This methods does not print anything.
- */
-private void printLine()
-{
-}
-
-}
+++ /dev/null
-/*\r
- * Copyright (c) 2003-2005 The BISON Project\r
- *\r
- * This program is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU Lesser General Public License version 2 as\r
- * published by the Free Software Foundation.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
- *\r
- */\r
-package peersim.config;\r
-import java.math.*;\r
-import org.lsmp.djep.groupJep.groups.*;\r
-import org.lsmp.djep.groupJep.interfaces.*;\r
-\r
-/**\r
- * This class implements the <code>Group</code> interface of JEP,\r
- * enabling the configuration system to read integers with arbitrary \r
- * length. \r
- */\r
-public class Operators extends Group implements IntegralDomainI,HasDivI,\r
- OrderedSetI,HasModI,HasPowerI {\r
- \r
-\r
- /**\r
- * Operations on the reals (Implemented as BigInteger).\r
- */\r
- public Operators() {\r
- }\r
-\r
- public Number getZERO() {\r
- return BigInteger.ZERO;\r
- }\r
-\r
- public Number getONE() {\r
- return BigInteger.ONE;\r
- }\r
-\r
- public Number getInverse(Number num) {\r
- if (num instanceof BigInteger) {\r
- BigInteger a = (BigInteger) num;\r
- return a.negate();\r
- } else {\r
- return -num.doubleValue();\r
- }\r
- }\r
-\r
- public Number add(Number num1, Number num2) {\r
- if (num1 instanceof Double || num2 instanceof Double) {\r
- // One is double\r
- return num1.doubleValue() + num2.doubleValue();\r
- } else {\r
- // Both integer\r
- BigInteger a = (BigInteger) num1;\r
- BigInteger b = (BigInteger) num2;\r
- return a.add(b);\r
- }\r
- }\r
-\r
- public Number sub(Number num1, Number num2) {\r
- if (num1 instanceof Double || num2 instanceof Double) {\r
- // One is double\r
- return num1.doubleValue() - num2.doubleValue();\r
- } else {\r
- // Both integer\r
- BigInteger a = (BigInteger) num1;\r
- BigInteger b = (BigInteger) num2;\r
- return a.subtract(b);\r
- }\r
- }\r
-\r
- public Number mul(Number num1, Number num2) {\r
- if (num1 instanceof Double || num2 instanceof Double) {\r
- // One is double\r
- return num1.doubleValue() * num2.doubleValue();\r
- } else {\r
- // Both integer\r
- BigInteger a = (BigInteger) num1;\r
- BigInteger b = (BigInteger) num2;\r
- return a.multiply(b);\r
- }\r
- }\r
-\r
- public Number div(Number num1, Number num2) {\r
- if (num1 instanceof Double || num2 instanceof Double) {\r
- // One is double\r
- return num1.doubleValue() / num2.doubleValue();\r
- } else {\r
- // Both integer\r
- BigInteger a = (BigInteger) num1;\r
- BigInteger b = (BigInteger) num2;\r
- return a.divide(b);\r
- }\r
- }\r
-\r
- \r
- public Number mod(Number num1, Number num2) {\r
- if (num1 instanceof Double || num2 instanceof Double) {\r
- // One is double\r
- return num1.doubleValue() % num2.doubleValue();\r
- } else {\r
- // Both integer\r
- BigInteger a = (BigInteger) num1;\r
- BigInteger b = (BigInteger) num2;\r
- return a.remainder(b);\r
- }\r
- }\r
- \r
- public Number pow(Number num1, Number num2) {\r
- if (num1 instanceof Double || num2 instanceof Double) {\r
- // One is double\r
- return Math.pow(num1.doubleValue(), num2.doubleValue());\r
- } else {\r
- // Both integer\r
- BigInteger a = (BigInteger) num1;\r
- BigInteger b = (BigInteger) num2;\r
- return a.pow(b.intValue());\r
- }\r
- }\r
- \r
- public boolean equals(Number num1, Number num2) {\r
- if (num1 instanceof Double || num2 instanceof Double) {\r
- // One is double\r
- return num1.doubleValue() == num2.doubleValue();\r
- } else {\r
- // Both integer\r
- BigInteger a = (BigInteger) num1;\r
- BigInteger b = (BigInteger) num2;\r
- return a.equals(b);\r
- }\r
- }\r
- \r
- public int compare(Number num1,Number num2) {\r
- if (num1 instanceof Double || num2 instanceof Double) {\r
- // One is double\r
- double n1 = num1.doubleValue();\r
- double n2 = num2.doubleValue();\r
- return (n1 < n2 ? -1 : (n1 == n2 ? 0 : 1));\r
- } else {\r
- // Both integer\r
- BigInteger a = (BigInteger) num1;\r
- BigInteger b = (BigInteger) num2;\r
- return a.compareTo(b);\r
- }\r
- }\r
-\r
- public Number valueOf(String str) {\r
- try {\r
- return new BigInteger(str);\r
- } catch (NumberFormatException e) {\r
- return new Double(str);\r
- }\r
- }\r
- \r
- public String toString() { return ""; }\r
-}\r
+++ /dev/null
-/*
- * 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.config;
-
-import java.io.*;
-import java.util.*;
-
-/**
-* Extends the class {@link ConfigProperties} with basic parsing capabilities.
-* @see #load
-*/
-public class ParsedProperties extends ConfigProperties {
-
-//================= variables ======================================
-//==================================================================
-
-// ================= initialization =================================
-// ==================================================================
-
-/**
-* Calls super constructor.
-* @see ConfigProperties#ConfigProperties(String[])
-*/
-public ParsedProperties( String[] pars ) {
-
- super( pars );
-}
-
-// ------------------------------------------------------------------
-
-/**
-* Calls super constructor.
-* @see ConfigProperties#ConfigProperties(String)
-*/
-public ParsedProperties( String filename ) throws IOException {
-
- super( filename );
-}
-
-
-// =========== Public methods ========================================
-// ===================================================================
-
-
-/**
-* Loads given file. It works exactly as <code>Properties.load</code>
-* with a file input stream to the given file, except that the file is parsed
-* the following way allowing to compress some property names
-* using <code>{</code> and <code>}</code>.
-
- When a bracket is present, it must
- be the only non-space element of a line. The last property defined
- before the opening bracket define the prefix that is added to all the
- properties defined included between brackets.
- In other words, a construct like this:
- <pre>
- control.degree GraphObserver
- {
- protocol newscast
- undir
- }
- </pre>
- is equivalent to the definition of these three properties:
- <pre>
- control.degree GraphObserver
- control.degree.protocol newscast
- control.degree.undir
- </pre>
-
- Nested brackets are possible. The rule of the last property before
- the opening bracket applies also to the inside brackets, with
- the prefix being the complete property definition (so, including
- the prefix observed before). Example:
- <pre>
- control.1 DynamicNetwork
- {
- add CRASH
- substitute
- init.0 WireKOut
- {
- degree DEGREE
- protocol 0
- }
- }
- </pre>
- defines the following properties:
- <pre>
- control.1 DynamicNetwork
- control.1.add CRASH
- control.1.substitute
- control.1.init.0 WireKOut
- control.1.init.0.degree DEGREE
- control.1.init.0.protocol 0
- </pre>
-
- <p>
- Know limitations:
- The parsing mechanism is very simple; no complex error messages
- are provided. In case of missing closing brackets, the method
- will stop reporting the number of missing brackets. Additional
- closing brackets (i.e., missing opening brackets) produce an
- error messages reporting the line where the closing bracket
- is present. Misplaced brackets (included in lines that
- contains other characters) are ignored, thus may indirectly produce
- the previous error messages.
-*/
-public void load( String fileName ) throws IOException {
-
- /* This set is used to store prefixes that have been associated
- * to brackets blocks. If a prefix is inserted twice, this means
- * that there are two blocks referring to the same prefix -
- * which may be caused by a commented prefix in the config
- * file, something like this:
- *
- * prefix1
- * {
- * property 1
- * }
- * #prefix2
- * {
- * property 2
- * }
- *
- */
- Set<String> prefixes = new HashSet<String>();
-
- BufferedReader f =
- new BufferedReader(new FileReader( fileName ));
- int lines = 0;
- parseStream(f, "", 0, lines, prefixes);
-
- f.close();
-}
-
-// --------------------------------------------------------------------
-
-private int parseStream(BufferedReader f, String prefix, int pars,
- int lines, Set prefixes)
-throws IOException {
-
- if (prefix.equals(".")) {
- System.err.println("Error at line " + lines + ": bracket block not " +
- "associated with any configuration entry");
- System.exit(1);
- }
- if (prefixes.contains(prefix)) {
- System.err.println("Error at line " + lines + ": multiple bracket " +
- "blocks referring to the same configuration entry " + prefix);
- System.exit(1);
- } else {
- prefixes.add(prefix);
- }
-
- boolean complete = true;
- String part;
- String line = "";
- String last = "";
- while ((part = f.readLine()) != null)
- {
- lines++;
-
- // Reset line
- if (complete) line = "";
-
- // Check if the line is a comment line
- // If so, remove the comment
- int index = part.indexOf('#');
- if (index >= 0)
- {
- part = part.substring(0, index);
- }
-
- // Check if the line is empty
- part = part.trim();
- if ("".equals(part)) continue;
-
- complete = (part.charAt(part.length()-1) != '\\');
- if (!complete)
- {
- line = line + part.substring(0, part.length()-2) + " ";
- continue;
- }
-
- // Complete the line
- line = line + part;
- if (line.equals("{"))
- {
- lines = parseStream(f, last+".", pars+1, lines, prefixes);
- }
- else if (line.equals("}"))
- {
- if (pars == 0)
- {
- System.err.println(
- "Error: Additional } at line " + lines +
- " when parsing the configuration file");
- System.exit(1);
- }
- return lines;
- }
- else
- {
- // Search the first token
- String[] tokens = line.split("[\\s:=]+", 2);
- if (tokens.length == 1)
- {
- setProperty(prefix+tokens[0], "");
- }
- else
- {
- setProperty(prefix+tokens[0], tokens[1]);
- }
- last = prefix + tokens[0];
- }
- }
- if (pars == 1)
- {
- System.err.println("Error: One closing bracket ('}') is missing");
- System.exit(1);
- }
- else if (pars > 1)
- {
- System.err.println("Error: " + pars+" closing brackets ('}') are missing");
- System.exit(1);
- }
- return lines;
-}
-
-// --------------------------------------------------------------------
-
-/*
-public static void main(String[] args)
-{
- java.util.Properties prop = new ParsedProperties(args);
-}
-*/
-}
-
+++ /dev/null
-/*
- * 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;
-
-/**
- * This interface must be implemented by protocols that need to release
- * some references when the fail state of their host node is set to
- * {@link Fallible#DEAD}. Recall that this fail state means that the node
- * will never get back online. However, other nodes and protocols might
- * still have references to these dead nodes and protocols, and this fact
- * is not always a bug. So implementing this interface allows for removing
- * stuff that we know is no longer necessary. Especially for linkable
- * protocols in the presence of churn, this is essential: they typically
- * have to release their links to other nodes to prevent the formation of
- * trees of removed nodes with a live reference to the root.
- */
-public interface Cleanable
-{
-
-/**
- * Performs cleanup when removed from the network. This is called by the
- * host node when its fail state is set to {@link Fallible#DEAD}.
- * It is very important that after calling this method, NONE of the methods
- * of the implementing object are guaranteed to work any longer.
- * They might throw arbitrary exceptions, etc. The idea is that after
- * calling this, typically no one should access this object.
- * However, as a recommendation, at least toString should be guaranteed to
- * execute normally, to aid debugging.
- */
-public void onKill();
-
-}
+++ /dev/null
-/*
- * 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 org.simgrid.msg.Msg;
-
-import peersim.Simulator;
-import peersim.config.*;
-import peersim.util.*;
-import psgsim.PSGPlatform;
-
-/**
- * This is the common state of the simulation all objects see.
- * Static singleton. One of its purposes is
- * simplification of parameter structures and increasing efficiency by putting
- * state information here instead of passing parameters.
- *<p>
- * <em>The set methods should not be used by applications</em>,
- * they are for system
- * components. Use them only if you know exactly what you are doing, e.g.
- * if you are so advanced that you can write your own simulation engine.
- * Ideally, they should not be visible, but due to the lack of more
- * flexibility in java access rights, we are forced to make them public.
- */
-public class CommonState
-{
-
-//======================= constants ===============================
-//=================================================================
-
-/**
-* Constant that can be used as a value of simulation phase.
-* It means that the simulation has finished.
-* @see #getPhase
-*/
-public static final int POST_SIMULATION = 1;
-
-/**
-* Constant that can be used as a value of simulation phase.
-* It means that the simulation phase information has not been set (unknown).
-* @see #getPhase
-*/
-public static final int PHASE_UNKNOWN = 0;
-
-// ======================= fields ==================================
-// =================================================================
-
-/**
- * Current time. Note that this value is simulator independent, all simulation
- * models have a notion related to time. For example, in the cycle based model,
- * the cycle id gives time, while in even driven simulations there is a more
- * realistic notion of time.
- */
-private static long time = 0;
-
-/**
- * The maximal value {@link #time} can ever take.
- */
-private static long endtime = -1;
-
-/**
- * Number of used bits in the long representation of time, calculated
- * based on the endtime.
- */
-private static int toshift = -1;
-
-/**
- * Information about where exactly the simulation is.
- */
-private static int phase = PHASE_UNKNOWN;
-
-/**
- * The current pid.
- */
-private static int pid;
-
-/**
- * The current node.
- */
-private static Node node;
-
-/**
-* This source of randomness should be used by all components.
-* This field is public because it doesn't matter if it changes
-* during an experiment (although it shouldn't) until no other sources of
-* randomness are used within the system. Besides, we can save the cost
-* of calling a wrapper method, which is important because this is needed
-* very often.
-*/
-public static ExtendedRandom r = null;
-
-
-// ======================== initialization =========================
-// =================================================================
-
-/**
-* Configuration parameter used to define which random generator
-* class should be used. If not specified, the default implementation
-* {@link ExtendedRandom} is used. User-specified random generators
-* must extend class {@link ExtendedRandom}.
-* @config
-*/
-public static final String PAR_RANDOM = "random";
-
-/**
-* Configuration parameter used to initialize the random seed.
-* If it is not specified the current time is used.
-* @config
-*/
-public static final String PAR_SEED = "random.seed";
-
-
-/**
-* Initializes the field {@link r} according to the configuration.
-* Assumes that the configuration is already
-* loaded.
-*/
-static {
-
- long seed =
- Configuration.getLong(PAR_SEED,System.currentTimeMillis());
- initializeRandom(seed);
-}
-
-
-/** Does nothing. To avoid construction but allow extension. */
-protected CommonState() {}
-
-// ======================= methods =================================
-// =================================================================
-
-
-/**
- * Returns current time. In event-driven simulations, returns the current
- * time (a long-value).
- * In cycle-driven simulations, returns the current cycle (a long that
- * can safely be cast into an integer).
- */
-public static long getTime()
-{
- /* if the engine simulator used is PSG (simId=2 */
- if(Simulator.getSimID()==2)
- return (long) PSGPlatform.getTime();
- else
- return time;
-}
-
-//-----------------------------------------------------------------
-
-/**
- * Returns current time in integer format. The purpose is to enhance the
- * performance of protocols (ints are smaller and faster) when absolute
- * precision is not required. It assumes that endtime has been set via
- * {@link #setEndTime} by the simulation engine. It uses the endtime for
- * the optimal mapping to get the maximal precision.
- * In particular, in the cycle
- * based model, time is the same as cycle which can be safely cast into
- * integer, so no precision is lost.
- */
-public static int getIntTime()
-{
- return (int)(time>>toshift);
-}
-
-//-----------------------------------------------------------------
-
-/**
- * Sets the current time.
- */
-public static void setTime(long t)
-{
- time = t;
-}
-
-//-----------------------------------------------------------------
-
-/**
- * Returns endtime.
- * It is the maximal value {@link #getTime} ever returns. If it's negative, it
- * means the endtime is not known.
- */
-public static long getEndTime()
-{
- return endtime;
-}
-
-//-----------------------------------------------------------------
-
-/**
- * Sets the endtime.
- */
-public static void setEndTime(long t)
-{
- if( endtime >= 0 )
- throw new RuntimeException("You can set endtime only once");
- if( t < 0 )
- throw new RuntimeException("No negative values are allowed");
-
- endtime = t;
- toshift = 32-Long.numberOfLeadingZeros(t);
- if( toshift<0 ) toshift = 0;
-}
-
-//-----------------------------------------------------------------
-
-/**
- * Returns the simulation phase. Currently the following phases are
- * understood.
- * <ul>
- * <li>{@link #PHASE_UNKNOWN} phase is unknown</li>
- * <li>{@link #POST_SIMULATION} the simulation is completed</li>
- * </ul>
- */
-public static int getPhase()
-{
- return phase;
-}
-
-// -----------------------------------------------------------------
-
-public static void setPhase(int p)
-{
- phase = p;
-}
-
-// -----------------------------------------------------------------
-
-/**
-* Returns the current protocol identifier. In other words, control is
-* held by the indicated protocol on node {@link #getNode}.
-*/
-public static int getPid()
-{
- return pid;
-}
-
-//-----------------------------------------------------------------
-
-/** Sets the current protocol identifier.*/
-public static void setPid(int p)
-{
- pid = p;
-}
-
-//-----------------------------------------------------------------
-
-/**
- * Returns the current node. When a protocol is executing, it is the node
- * hosting the protocol.
- */
-public static Node getNode()
-{
- return node;
-}
-
-//-----------------------------------------------------------------
-
-/** Sets the current node */
-public static void setNode(Node n)
-{
- node = n;
-}
-
-//-----------------------------------------------------------------
-
-public static void initializeRandom(long seed)
-{
- if (r == null) {
- r = (ExtendedRandom) Configuration.getInstance(PAR_RANDOM, new ExtendedRandom(seed));
- }
- r.setSeed(seed);
-}
-
-//-----------------------------------------------------------------
-
-/*
-public static void main(String pars[]) {
-
- setEndTime(Long.parseLong(pars[0]));
- setTime(Long.parseLong(pars[1]));
- System.err.println(getTime()+" "+getIntTime());
-}
-*/
-}
-
+++ /dev/null
-/*
- * 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;
-
-/**
- * Generic interface for classes that are responsible for observing or modifying
- * the ongoing simulation. It is designed to allow maximal flexibility therefore
- * poses virtually no restrictions on the implementation.
- */
-public interface Control
-{
-
-/**
- * Performs arbitrary modifications or reports arbitrary information over the
- * components.
- * @return true if the simulation has to be stopped, false otherwise.
- */
-public boolean execute();
-
-}
+++ /dev/null
-/*
- * 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;
-
-
-/**
-* Instances of classes implementing this interface
-* maintain a fail state, i.e. information about the availability
-* of the object.
-*/
-public interface Fallible {
-
-
- /**
- * Fail state which indicates that the object is operating normally.
- */
- public int OK = 0;
-
- /**
- * Fail state indicating that the object is dead and recovery is
- * not possible. When this state is set, it is a good idea to make sure
- * that the state of the object becomes such that any attempt to
- * operate on it causes a visible error of some kind.
- */
- public int DEAD = 1;
-
- /**
- * Fail state indicating that the object is not dead, but is temporarily
- * not accessible.
- */
- public int DOWN = 2;
-
- /**
- * Returns the state of this object. Must be one of the constants
- * defined in interface {@link Fallible}.
- */
- public int getFailState();
-
- /**
- * Sets the fails state of this object. Parameter must be one of the
- * constants defined in interface {@link Fallible}.
- */
- public void setFailState(int failState);
-
- /**
- * Convenience method to check if the node is up and running
- * @return must return true if and only if
- * <code>getFailState()==OK</code>
- */
- public boolean isUp();
-}
-
-
+++ /dev/null
-/*
- * 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.*;
-
-/**
-* This is the default {@link Node} class that is used to compose the
-* {@link Network}.
-*/
-public class GeneralNode implements Node {
-
-
-// ================= fields ========================================
-// =================================================================
-
-/** used to generate unique IDs */
-private static long counterID = -1;
-
-/**
-* The protocols on this node.
-*/
-protected Protocol[] protocol = null;
-
-/**
-* The current index of this node in the node
-* list of the {@link Network}. It can change any time.
-* This is necessary to allow
-* the implementation of efficient graph algorithms.
-*/
-private int index;
-
-/**
-* The fail state of the node.
-*/
-protected int failstate = Fallible.OK;
-
-/**
-* The ID of the node. It should be final, however it can't be final because
-* clone must be able to set it.
-*/
-private long ID;
-
-// ================ constructor and initialization =================
-// =================================================================
-
-/** Used to construct the prototype node. This class currently does not
-* have specific configuration parameters and so the parameter
-* <code>prefix</code> is not used. It reads the protocol components
-* (components that have type {@value peersim.core.Node#PAR_PROT}) from
-* the configuration.
-*/
-public GeneralNode(String prefix) {
-
- String[] names = Configuration.getNames(PAR_PROT);
- CommonState.setNode(this);
- ID=nextID();
- protocol = new Protocol[names.length];
- for (int i=0; i < names.length; i++) {
- CommonState.setPid(i);
- Protocol p = (Protocol)
- Configuration.getInstance(names[i]);
- protocol[i] = p;
- }
-}
-
-
-// -----------------------------------------------------------------
-
-public Object clone() {
-
- GeneralNode result = null;
- try { result=(GeneralNode)super.clone(); }
- catch( CloneNotSupportedException e ) {} // never happens
- result.protocol = new Protocol[protocol.length];
- CommonState.setNode(result);
- result.ID=nextID();
- for(int i=0; i<protocol.length; ++i) {
- CommonState.setPid(i);
- result.protocol[i] = (Protocol)protocol[i].clone();
- }
- return result;
-}
-
-// -----------------------------------------------------------------
-
-/** returns the next unique ID */
-private long nextID() {
-
- return counterID++;
-}
-
-// =============== public methods ==================================
-// =================================================================
-
-
-public void setFailState(int failState) {
-
- // after a node is dead, all operations on it are errors by definition
- if(failstate==DEAD && failState!=DEAD) throw new IllegalStateException(
- "Cannot change fail state: node is already DEAD");
- switch(failState)
- {
- case OK:
- failstate=OK;
- break;
- case DEAD:
- //protocol = null;
- index = -1;
- failstate = DEAD;
- for(int i=0;i<protocol.length;++i)
- if(protocol[i] instanceof Cleanable)
- ((Cleanable)protocol[i]).onKill();
- break;
- case DOWN:
- failstate = DOWN;
- break;
- default:
- throw new IllegalArgumentException(
- "failState="+failState);
- }
-}
-
-// -----------------------------------------------------------------
-
-public int getFailState() { return failstate; }
-
-// ------------------------------------------------------------------
-
-public boolean isUp() { return failstate==OK; }
-
-// -----------------------------------------------------------------
-
-public Protocol getProtocol(int i) { return protocol[i]; }
-
-//------------------------------------------------------------------
-
-public int protocolSize() { return protocol.length; }
-
-//------------------------------------------------------------------
-
-public int getIndex() { return index; }
-
-//------------------------------------------------------------------
-
-public void setIndex(int index) { this.index = index; }
-
-//------------------------------------------------------------------
-
-/**
-* Returns the ID of this node. The IDs are generated using a counter
-* (i.e. they are not random).
-*/
-public long getID() { return ID; }
-
-//------------------------------------------------------------------
-
-public String toString()
-{
- StringBuffer buffer = new StringBuffer();
- buffer.append("ID: "+ID+" index: "+index+"\n");
- for(int i=0; i<protocol.length; ++i)
- {
- buffer.append("protocol["+i+"]="+protocol[i]+"\n");
- }
- return buffer.toString();
-}
-
-//------------------------------------------------------------------
-
-/** Implemented as <code>(int)getID()</code>. */
-public int hashCode() { return (int)getID(); }
-
-}
-
-
+++ /dev/null
-/*
- * 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;
-
-/**
- * A protocol that stores links. It does nothing apart from that.
- * It is useful to model a static link-structure
- * (topology). The only function of this protocol is to serve as a source of
- * neighborhood information for other protocols.
- */
-public class IdleProtocol implements Protocol, Linkable
-{
-
-// --------------------------------------------------------------------------
-// Parameters
-// --------------------------------------------------------------------------
-
-/**
- * Default init capacity
- */
-private static final int DEFAULT_INITIAL_CAPACITY = 10;
-
-/**
- * Initial capacity. Defaults to {@value #DEFAULT_INITIAL_CAPACITY}.
- * @config
- */
-private static final String PAR_INITCAP = "capacity";
-
-// --------------------------------------------------------------------------
-// Fields
-// --------------------------------------------------------------------------
-
-/** Neighbors */
-protected Node[] neighbors;
-
-/** Actual number of neighbors in the array */
-protected int len;
-
-// --------------------------------------------------------------------------
-// Initialization
-// --------------------------------------------------------------------------
-
-public IdleProtocol(String s)
-{
- neighbors = new Node[Configuration.getInt(s + "." + PAR_INITCAP,
- DEFAULT_INITIAL_CAPACITY)];
- len = 0;
-}
-
-//--------------------------------------------------------------------------
-
-public Object clone()
-{
- IdleProtocol ip = null;
- try { ip = (IdleProtocol) super.clone(); }
- catch( CloneNotSupportedException e ) {} // never happens
- ip.neighbors = new Node[neighbors.length];
- System.arraycopy(neighbors, 0, ip.neighbors, 0, len);
- ip.len = len;
- return ip;
-}
-
-// --------------------------------------------------------------------------
-// Methods
-// --------------------------------------------------------------------------
-
-public boolean contains(Node n)
-{
- for (int i = 0; i < len; i++) {
- if (neighbors[i] == n)
- return true;
- }
- return false;
-}
-
-// --------------------------------------------------------------------------
-
-/** Adds given node if it is not already in the network. There is no limit
-* to the number of nodes that can be added. */
-public boolean addNeighbor(Node n)
-{
- for (int i = 0; i < len; i++) {
- if (neighbors[i] == n)
- return false;
- }
- if (len == neighbors.length) {
- Node[] temp = new Node[3 * neighbors.length / 2];
- System.arraycopy(neighbors, 0, temp, 0, neighbors.length);
- neighbors = temp;
- }
- neighbors[len] = n;
- len++;
- return true;
-}
-
-// --------------------------------------------------------------------------
-
-public Node getNeighbor(int i)
-{
- return neighbors[i];
-}
-
-// --------------------------------------------------------------------------
-
-public int degree()
-{
- return len;
-}
-
-// --------------------------------------------------------------------------
-
-public void pack()
-{
- if (len == neighbors.length)
- return;
- Node[] temp = new Node[len];
- System.arraycopy(neighbors, 0, temp, 0, len);
- neighbors = temp;
-}
-
-// --------------------------------------------------------------------------
-
-public String toString()
-{
- if( neighbors == null ) return "DEAD!";
- StringBuffer buffer = new StringBuffer();
- buffer.append("len=" + len + " maxlen=" + neighbors.length + " [");
- for (int i = 0; i < len; ++i) {
- buffer.append(neighbors[i].getIndex() + " ");
- }
- return buffer.append("]").toString();
-}
-
-// --------------------------------------------------------------------------
-
-public void onKill()
-{
- neighbors = null;
- len = 0;
-}
-
-}
+++ /dev/null
-/*
- * 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;
-
-
-/**
-* Instances of classes implementing this interface can form networks (graphs)
-* in the simulator framework.
-* The interface is similar to one of a container (containing neighbors),
-* only the types of the contained elements have to be {@link Node}.
-* The neighbor collection is defined in a random access list style, but
-* it must follow the contract of a set too (elements must be unique).
-* <p>
-* Also note that there is no possibility to remove elements from the
-* neighbor set. This is because removal is usually costly and it does not make
-* sense in the context of our applications,
-* where this interface is used for 1) initialization and 2)
-* providing an interface for other protocols for accessing the neighbor list.
-* Protocols that manage links remove, refresh, etc their link set internally
-* or through custom methods.
-* Therefore it would only put an unnecessary burden on implementors.
-*/
-public interface Linkable extends Cleanable {
-
-
- /**
- * Returns the size of the neighbor list.
- */
- public int degree();
-
- /**
- * Returns the neighbor with the given index. The contract is that
- * listing the elements from index 0 to index degree()-1 should list
- * each element exactly once if this object is not modified in the
- * meantime. It throws an IndexOutOfBounds exception if i is negative
- * or larger than or equal to {@link #degree}.
- */
- public Node getNeighbor(int i);
-
- /**
- * Add a neighbor to the current set of neighbors. If neighbor
- * is not yet a neighbor but it cannot be added from other reasons,
- * this method should not return normally, that is, it must throw
- * a runtime exception.
- * @return true if the neighbor has been inserted; false if the
- * node is already a neighbor of this node
- */
- public boolean addNeighbor(Node neighbour);
-
- /**
- * Returns true if the given node is a member of the neighbor set.
- */
- public boolean contains(Node neighbor);
-
- /**
- * A possibility for optimization. An implementation should try to
- * compress its internal representation. Normally this is called
- * by initializers or other components when
- * no increase in the expected size of the neighborhood can be
- * expected.
- */
- public void pack();
-}
-
+++ /dev/null
-/*
- * 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;
-
-/**
- * Tag interface to identify protocols that are malicious.
- *
- * @author Alberto Montresor
- * @version $Revision: 1.2 $
- */
-public interface MaliciousProtocol
-extends Protocol
-{
-}
-
+++ /dev/null
-/*
- * 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;
-
-
-/**
- * This class extends GeneralNode by allowing to modify single
- * protocol instances at nodes.
- *
- * @author Alberto Montresor
- * @version $Revision: 1.3 $
- */
-public class ModifiableNode extends GeneralNode
-{
-
-/**
- * Invokes the super constructor.
- */
-public ModifiableNode(String prefix)
-{
- super(prefix);
-}
-
-/**
- * Substitutes the specified protocol at this node.
- *
- * @param pid protocol identifier
- * @param prot the protocol object
- */
-public void setProtocol(int pid, Protocol prot)
-{
- protocol[pid] = prot;
-}
-
-}
+++ /dev/null
-/*
- * 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.Simulator;
-import peersim.config.Configuration;
-import psgsim.PSGDynamicNetwork;
-
-import java.util.Comparator;
-import java.util.Arrays;
-
-import org.simgrid.msg.HostNotFoundException;
-import org.simgrid.msg.MsgException;
-
-/**
- * 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++;
- if (Simulator.getSimID() == 2)
- try {
- PSGDynamicNetwork.add(n);
- } catch (HostNotFoundException e) {
- System.err.println("Host not found in platform file");
- }
- System.err.println("node " + n.getID() + " with index " + n.getIndex()
- + " was added at time " + CommonState.getTime());
- }
-
- // ------------------------------------------------------------------
-
- /**
- * 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--;
- System.err.println("node " + n.getID() + " with index " + n.getIndex()
- + " was removed at time " + CommonState.getTime());
- n.setFailState(Fallible.DEAD);
- if (Simulator.getSimID() == 2)
- PSGDynamicNetwork.remove(n);
- 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);
- }
- }
-
-}
+++ /dev/null
-/*
- * 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;
-
-/**
- * Class that represents one node with a network address. An {@link Network} is
- * made of a set of nodes. The functionality of this class is thin: it must be
- * able to represent failure states and store a list of protocols. It is the
- * protocols that do the interesting job.
- */
-public interface Node extends Fallible, Cloneable
-{
-
-/**
- * Prefix of the parameters that defines protocols.
- * @config
- */
-public static final String PAR_PROT = "protocol";
-
-/**
- * Returns the <code>i</code>-th protocol in this node. If <code>i</code>
- * is not a valid protocol id
- * (negative or larger than or equal to the number of protocols), then it throws
- * IndexOutOfBoundsException.
- */
-public Protocol getProtocol(int i);
-
-/**
- * Returns the number of protocols included in this node.
- */
-public int protocolSize();
-
-/**
- * Sets the index of this node in the internal representation of the node list.
- * Applications should not use this method. It is defined as public simply
- * because it is not possible to define it otherwise.
- * Using this method will result in
- * undefined behavior. It is provided for the core system.
- */
-public void setIndex(int index);
-
-/**
- * Returns the index of this node. It is such that
- * <code>Network.get(n.getIndex())</code> returns n. This index can
- * change during a simulation, it is not a fixed id. If you need that, use
- * {@link #getID}.
- * @see Network#get
- */
-public int getIndex();
-
-/**
-* Returns the unique ID of the node. It is guaranteed that the ID is unique
-* during the entire simulation, that is, there will be no different Node
-* objects with the same ID in the system during one invocation of the JVM.
-* Preferably nodes
-* should implement <code>hashCode()</code> based on this ID.
-*/
-public long getID();
-
-/**
- * Clones the node. It is defined as part of the interface
- * to change the access right to public and to get rid of the
- * <code>throws</code> clause.
- */
-public Object clone();
-
-}
+++ /dev/null
-/*
- * 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;
-
-/**
-* A protocol that does nothing but knows everything.
-* It provides an interface which models a protocol that knows all nodes
-* in the network, i.e. the neighborhood set of this protocol is always the
-* whole node set. this protocol is also extremely cheap, in fact it
-* has no data fields.
-*/
-public final class OracleIdleProtocol implements Protocol, Linkable {
-
-// =================== initialization, creation ======================
-// ===================================================================
-
-
-/** Does nothing */
-public OracleIdleProtocol(String prefix) {}
-
-// --------------------------------------------------------------------
-
-/** Returns <tt>this</tt> to maximize memory saving. It contains no fields.*/
-public Object clone() { return this; }
-
-
-// ===================== public methods ===============================
-// ====================================================================
-
-
-/** This is an expensive operation, should not be used at all.
-* It returns false only if the given node is not in the current network.
-*/
-public boolean contains(Node n) {
-
- final int len = Network.size();
- for (int i=0; i < len; i++)
- {
- if (Network.node[i] == n)
- return true;
- }
- return false;
-}
-
-// --------------------------------------------------------------------
-
-/** Unsupported operation */
-public boolean addNeighbor(Node n) {
-
- throw new UnsupportedOperationException();
-}
-
-// --------------------------------------------------------------------
-
-/**
-* The neighborhood contains the node itself, ie it contains the loop
-* edge.
-*/
-public Node getNeighbor(int i) {
-
- return Network.node[i];
-}
-
-// --------------------------------------------------------------------
-
-public int degree() {
-
- return Network.size();
-}
-
-// --------------------------------------------------------------------
-
-public void pack() {}
-
-// --------------------------------------------------------------------
-
-public void onKill() {}
-
-// --------------------------------------------------------------------
-
-public String toString() {
-
- return degree()+" [all the nodes of the overlay network]";
-}
-
-}
-
+++ /dev/null
-/*
- * 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.graph.Graph;
-import java.util.Collection;
-import java.util.ArrayList;
-import java.util.Collections;
-
-/**
-* This class is an adaptor which makes a {@link Linkable} protocol layer
-* look like a graph. It is useful because it allows the application of many
-* graph algorithms and graph topology initialization methods.
-* If the overlay network changes after creating this object, the changes
-* will be reflected. However, if the nodes are reshuffled (see
-* {@link Network#shuffle}), or if the node list changes (addition/removal),
-* then the behaviour becomes unspecified.
-*
-* The indices of nodes are from 0 to Network.size()-1.
-*
-* The fail state of nodes has an effect on the graph: all nodes are included
-* but edges are included only if both ends are up. This expresses the fact
-* that this graph is in fact defined by the "can communicate with" relation.
-*/
-public class OverlayGraph implements Graph {
-
-
-// ====================== fields ================================
-// ==============================================================
-
-/**
-* The protocol ID that selects the Linkable protocol to convert to a graph.
-*/
-public final int protocolID;
-
-/**
-* Tells if the graph should be wired in an undirected way.
-* Method {@link #directed} returns true always, this affects only
-* method {@link #setEdge}: if false, then the opposite edge is set too.
-*/
-public final boolean wireDirected;
-
-// ====================== public constructors ===================
-// ==============================================================
-
-/**
-* @param protocolID The protocol on which this adaptor is supposed
-* to operate.
-*/
-public OverlayGraph( int protocolID ) {
-
- this.protocolID = protocolID;
- wireDirected = true;
-}
-
-// --------------------------------------------------------------
-
-/**
-* @param protocolID The protocol on which this adaptor is supposed
-* to operate.
-* @param wireDirected specifies if {@link #setEdge} would wire the
-* opposite edge too.
-*/
-public OverlayGraph( int protocolID, boolean wireDirected ) {
-
- this.protocolID = protocolID;
- this.wireDirected = wireDirected;
-}
-
-
-// ======================= Graph implementations ================
-// ==============================================================
-
-
-public boolean isEdge(int i, int j) {
-
- return
- ((Linkable)Network.node[i].getProtocol(protocolID)
- ).contains(Network.node[j]) &&
- Network.node[j].isUp() &&
- Network.node[i].isUp();
-}
-
-// ---------------------------------------------------------------
-
-/**
-* Returns those neighbors that are up. If node i is not up, it returns
-* an empty list.
-*/
-public Collection<Integer> getNeighbours(int i) {
-
- Linkable lble=(Linkable)Network.node[i].getProtocol(protocolID);
- ArrayList<Integer> al = new ArrayList<Integer>(lble.degree());
- if( Network.node[i].isUp() )
- {
- for(int j=0; j<lble.degree(); ++j)
- {
- final Node n = lble.getNeighbor(j);
- // if accessible, we include it
- if(n.isUp()) al.add(Integer.valueOf(n.getIndex()));
- }
- }
- return Collections.unmodifiableList(al);
-}
-
-// ---------------------------------------------------------------
-
-/** Returns <code>Network.node[i]</code> */
-public Object getNode(int i) { return Network.node[i]; }
-
-// ---------------------------------------------------------------
-
-/**
-* Returns null always
-*/
-public Object getEdge(int i, int j) { return null; }
-
-// ---------------------------------------------------------------
-
-/** Returns <code>Network.size()</code> */
-public int size() { return Network.size(); }
-
-// --------------------------------------------------------------------
-
-/** Returns always true */
-public boolean directed() { return true; }
-
-// --------------------------------------------------------------------
-
-/**
-* Sets given edge.
-* In some cases this behaves strangely. Namely, when node i or j is not up,
-* but is not dead (e.g. it can be down temporarily).
-* In such situations the relevant link is made, but afterwards
-* getEdge(i,j) will NOT return true, only when the fail state has changed back
-* to OK.
-*
-* <p>Conceptually one can think of it as a successful operation which is
-* immediately overruled by the dynamics of the underlying overlay network.
-* Let's not forget that this class is an adaptor only.
-*
-* <p>
-* The behaviour of this method is affected by parameter {@link #wireDirected}.
-* If it is false, then the opposite edge is set too.
-*/
-public boolean setEdge( int i, int j ) {
-// XXX slightly unintuitive behavior but makes sense when understood
-
- if( !wireDirected )
- ((Linkable)Network.node[j].getProtocol(protocolID)
- ).addNeighbor(Network.node[i]);
-
-
- return
- ((Linkable)Network.node[i].getProtocol(protocolID)
- ).addNeighbor(Network.node[j]);
-}
-
-// ---------------------------------------------------------------
-
-/** Not supported */
-public boolean clearEdge( int i, int j ) {
-
- throw new UnsupportedOperationException();
-}
-
-// ---------------------------------------------------------------
-
-/**
-* Returns number of neighbors that are up. If node i is down, returns 0.
-*/
-public int degree(int i) {
-
- if( !Network.node[i].isUp() ) return 0;
- Linkable lble=(Linkable)Network.node[i].getProtocol(protocolID);
- int numNeighbours = 0;
- for(int j=0; j<lble.degree(); ++j)
- {
- final Node n = lble.getNeighbor(j);
- // if accessible, we count it
- if(n.isUp()) numNeighbours++;
- }
- return numNeighbours;
-}
-
-
-// ========================= other methods =======================
-// ===============================================================
-
-
-/**
-* Returns number of neighbors that are either up or down.
-* If node i is down, returns 0.
-*/
-public int fullDegree(int i) {
-
- if( !Network.node[i].isUp() ) return 0;
- Linkable lble=(Linkable)Network.node[i].getProtocol(protocolID);
- return lble.degree();
-}
-
-
-}
-
-
+++ /dev/null
-/*
- * 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;
-
-/**
- * Interface to identify protocols.
- *
- * @author Alberto Montresor
- * @version $Revision: 1.5 $
- */
-public interface Protocol extends Cloneable
-{
-
-/**
- * Returns a clone of the protocol. It is important to pay attention to
- * implement this carefully because in peersim all nodes are generated by
- * cloning except a prototype node. That is, the constructor of protocols is
- * used only to construct the prototype. Initialization can be done
- * via {@link Control}s.
- */
-public Object clone();
-
-}
+++ /dev/null
-/*
- * 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.*;
-
-// XXX a quite primitive scheduler, should be able to be configured
-// much more flexibly using a simple syntax for time ranges.
-/**
-* A binary function over the time points. That is,
-* for each time point returns a boolean value.
-*
-* The concept of time depends on the simulation model. Current time
-* has to be set by the simulation engine, irrespective of the model,
-* and can be read using {@link CommonState#getTime()}. This scheduler
-* is interpreted over those time points.
-*
-* <p>In this simple implementation the valid times will be
-* <tt>from, from+step, from+2*step, etc,</tt>
-* where the last element is strictly less than <tt>until</tt>.
-* Alternatively, if <tt>at</tt> is defined, then the schedule will be a single
-* time point. If FINAL is
-* defined, it is also added to the set of active time points.
-* It refers to the time after the simulation has finished (see
-* {@link CommonState#getPhase}).
-*/
-public class Scheduler {
-
-
-// ========================= fields =================================
-// ==================================================================
-
-
-/**
-* Defaults to 1.
-* @config
-*/
-private static final String PAR_STEP = "step";
-
-/**
-* Defaults to -1. That is, defaults to be ineffective.
-* @config
-*/
-private static final String PAR_AT = "at";
-
-
-/**
-* Defaults to 0.
-* @config
-*/
-private static final String PAR_FROM = "from";
-
-/**
-* Defaults to <tt>Long.MAX_VALUE</tt>.
-* @config
-*/
-private static final String PAR_UNTIL = "until";
-
-/**
-* Defines if component is active after the simulation has finished.
-* Note that the exact time the simulation finishes is not know in advance
-* because other components can stop the simulation at any time.
-* By default not set.
-* @see CommonState#getPhase
-* @config
-*/
-private static final String PAR_FINAL = "FINAL";
-
-public final long step;
-
-public final long from;
-
-public final long until;
-
-public final boolean fin;
-
-/** The next scheduled time point.*/
-protected long next = -1;
-
-// ==================== initialization ==============================
-// ==================================================================
-
-
-/** Reads configuration parameters from the component defined by
-* <code>prefix</code>. {@value #PAR_STEP} defaults to 1.
-*/
-public Scheduler(String prefix) {
-
- this(prefix, true);
-}
-
-// ------------------------------------------------------------------
-
-/** Reads configuration parameters from the component defined by
-* <code>prefix</code>. If useDefault is false, then at least parameter
-* {@value #PAR_STEP} must be explicitly defined. Otherwise {@value #PAR_STEP}
-* defaults to 1.
-*/
-public Scheduler(String prefix, boolean useDefault)
-{
- if (Configuration.contains(prefix+"."+PAR_AT)) {
- // FROM, UNTIL, and STEP should *not* be defined
- if (Configuration.contains(prefix+"."+PAR_FROM) ||
- Configuration.contains(prefix+"."+PAR_UNTIL) ||
- Configuration.contains(prefix+"."+PAR_STEP))
- throw new IllegalParameterException(prefix,
- "Cannot use \""+PAR_AT+"\" together with \""
- +PAR_FROM+"\", \""+PAR_UNTIL+"\", or \""+
- PAR_STEP+"\"");
-
- from = Configuration.getLong(prefix+"."+PAR_AT);
- until = from+1;
- step = 1;
- } else {
- if (useDefault)
- step = Configuration.getLong(prefix+"."+PAR_STEP,1);
- else
- step = Configuration.getLong(prefix+"."+PAR_STEP);
- if( step < 1 )
- throw new IllegalParameterException(prefix,
- "\""+PAR_STEP+"\" must be >= 1");
-
- from = Configuration.getLong(prefix+"."+PAR_FROM,0);
- until = Configuration.getLong(prefix+"."+PAR_UNTIL,Long.MAX_VALUE);
- }
-
- if( from < until ) next = from;
- else next = -1;
-
- fin = Configuration.contains(prefix+"."+PAR_FINAL);
-}
-
-
-// ===================== public methods ==============================
-// ===================================================================
-
-/** true if given time point is covered by this scheduler */
-public boolean active(long time) {
-
- if( time < from || time >= until ) return false;
- return (time - from)%step == 0;
-}
-
-// -------------------------------------------------------------------
-
-/** true if current time point is covered by this scheduler */
-public boolean active() {
-
- return active( CommonState.getTime() );
-}
-
-//-------------------------------------------------------------------
-
-/**
-* Returns the next time point. If the returned value is negative, there are
-* no more time points. As a side effect, it also updates the next time point,
-* so repeated calls to this method return the scheduled times.
-*/
-public long getNext()
-{
- long ret = next;
- // check like this to prevent integer overflow of "next"
- if( until-next > step ) next += step;
- else next = -1;
- return ret;
-}
-
-}
-
-
+++ /dev/null
-/*
- * 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.dynamics;
-
-import java.util.Map;
-
-import org.simgrid.msg.Host;
-import org.simgrid.msg.MsgException;
-
-import peersim.Simulator;
-import peersim.config.Configuration;
-import peersim.core.*;
-import psgsim.NodeHost;
-import psgsim.PSGDynamicNetwork;
-
-/**
- * This {@link Control} can change the size of networks by adding and removing
- * nodes. Can be used to model churn. This class supports only permanent removal
- * of nodes and the addition of brand new nodes. That is, temporary downtime is
- * not supported by this class.
- */
-public class DynamicNetwork implements Control {
-
- // --------------------------------------------------------------------------
- // Parameters
- // --------------------------------------------------------------------------
-
- /**
- * Config parameter which gives the prefix of node initializers. An
- * arbitrary number of node initializers can be specified (Along with their
- * parameters). These will be applied on the newly created nodes. The
- * initializers are ordered according to alphabetical order if their ID.
- * Example:
- *
- * <pre>
- * control.0 DynamicNetwork
- * control.0.init.0 RandNI
- * control.0.init.0.k 5
- * control.0.init.0.protocol somelinkable
- * ...
- * </pre>
- *
- * @config
- */
- private static final String PAR_INIT = "init";
-
- /**
- * If defined, nodes are substituted (an existing node is removed, a new one
- * is added. That is, first the number of nodes to add (or remove if
- * {@value #PAR_ADD} is negative) is calculated, and then exactly the same
- * number of nodes are removed (or added) immediately so that the network
- * size remains constant. Not set by default.
- *
- * @config
- */
- private static final String PAR_SUBST = "substitute";
-
- /**
- * Specifies the number of nodes to add or remove. It can be negative in
- * which case nodes are removed. If its absolute value is less than one,
- * then it is interpreted as a proportion of current network size, that is,
- * its value is substituted with <tt>add*networksize</tt>. Its value is
- * rounded to an integer.
- *
- * @config
- */
- private static final String PAR_ADD = "add";
-
- /**
- * Nodes are added until the size specified by this parameter is reached.
- * The network will never exceed this size as a result of this class. If not
- * set, there will be no limit on the size of the network.
- *
- * @config
- */
- private static final String PAR_MAX = "maxsize";
-
- /**
- * Nodes are removed until the size specified by this parameter is reached.
- * The network will never go below this size as a result of this class.
- * Defaults to 0.
- *
- * @config
- */
- private static final String PAR_MIN = "minsize";
-
- // --------------------------------------------------------------------------
- // Fields
- // --------------------------------------------------------------------------
-
- /** value of {@value #PAR_ADD} */
- protected final double add;
-
- /** value of {@value #PAR_SUBST} */
- protected final boolean substitute;
-
- /** value of {@value #PAR_MIN} */
- protected final int minsize;
-
- /** value of {@value #PAR_MAX} */
- protected final int maxsize;
-
- /** node initializers to apply on the newly added nodes */
- protected final NodeInitializer[] inits;
-
- // --------------------------------------------------------------------------
- // Protected methods
- // --------------------------------------------------------------------------
-
- /**
- * Adds n nodes to the network. Extending classes can implement any
- * algorithm to do that. The default algorithm adds the given number of
- * nodes after calling all the configured initializers on them.
- *
- * @param n
- * the number of nodes to add, must be non-negative.
- */
- protected void add(int n) {
- for (int i = 0; i < n; ++i) {
- Node newnode = (Node) Network.prototype.clone();
- for (int j = 0; j < inits.length; ++j) {
- inits[j].initialize(newnode);
- }
- Network.add(newnode);
-
- }
- }
-
- // ------------------------------------------------------------------
-
- /**
- * Removes n nodes from the network. Extending classes can implement any
- * algorithm to do that. The default algorithm removes <em>random</em> nodes
- * <em>permanently</em> simply by calling {@link Network#remove(int)}.
- *
- * @param n
- * the number of nodes to remove
- */
- protected void remove(int n) {
- for (int i = 0; i < n; ++i) {
- int nr = CommonState.r.nextInt(Network.size());
- Network.remove(nr);
-
- }
- }
-
- // --------------------------------------------------------------------------
- // Initialization
- // --------------------------------------------------------------------------
-
- /**
- * Standard constructor that reads the configuration parameters. Invoked by
- * the simulation engine.
- *
- * @param prefix
- * the configuration prefix for this class
- */
- public DynamicNetwork(String prefix) {
- add = Configuration.getDouble(prefix + "." + PAR_ADD);
- substitute = Configuration.contains(prefix + "." + PAR_SUBST);
- Object[] tmp = Configuration.getInstanceArray(prefix + "." + PAR_INIT);
- inits = new NodeInitializer[tmp.length];
- for (int i = 0; i < tmp.length; ++i) {
- // System.out.println("Inits " + tmp[i]);
- inits[i] = (NodeInitializer) tmp[i];
- }
- maxsize = Configuration.getInt(prefix + "." + PAR_MAX,
- Integer.MAX_VALUE);
- minsize = Configuration.getInt(prefix + "." + PAR_MIN, 0);
- }
-
- // --------------------------------------------------------------------------
- // Public methods
- // --------------------------------------------------------------------------
-
- /**
- * Calls {@link #add(int)} or {@link #remove} with the parameters defined by
- * the configuration.
- *
- * @return always false
- */
- public final boolean execute() {
- if (add == 0)
- return false;
- if (!substitute) {
- if ((maxsize <= Network.size() && add > 0)
- || (minsize >= Network.size() && add < 0))
- return false;
- }
- int toadd = 0;
- int toremove = 0;
- if (add > 0) {
- toadd = (int) Math.round(add < 1 ? add * Network.size() : add);
- if (!substitute && toadd > maxsize - Network.size())
- toadd = maxsize - Network.size();
- if (substitute)
- toremove = toadd;
- } else if (add < 0) {
- toremove = (int) Math
- .round(add > -1 ? -add * Network.size() : -add);
- if (!substitute && toremove > Network.size() - minsize)
- toremove = Network.size() - minsize;
- if (substitute)
- toadd = toremove;
- }
- remove(toremove);
- add(toadd);
- return false;
- }
-
- // --------------------------------------------------------------------------
-
-}
+++ /dev/null
-/*
- * 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.dynamics;
-
-import java.lang.reflect.*;
-import peersim.config.*;
-import peersim.core.*;
-import java.util.ArrayList;
-
-/**
- * This {@link Control} invokes a specified method on a protocol.
- * The method is defined by config parameter {@value #PAR_METHOD} and
- * the protocol is by {@value #PAR_PROT}. The method must not have any
- * parameters and must return void. If no protocol is specified, then the
- * method will be invoked on all protocol in the protocol stack that define
- * it.
- * <p>
- * Although the method cannot have any parameters, it can of course read
- * {@link CommonState}. It is guaranteed that the state is up-to-date,
- * inlcuding eg method {@link CommonState#getNode}.
- */
-public class MethodInvoker implements Control, NodeInitializer {
-
-
-// --------------------------------------------------------------------------
-// Parameter names
-// --------------------------------------------------------------------------
-
-/**
- * The protocol to operate on.
- * If not defined, the given method will be invoked on all protocols that
- * define it. In all cases, at least one protocol has to define it.
- * @config
- */
-private static final String PAR_PROT = "protocol";
-
-/**
- * The method to be invoked. It must return void and should not have any
- * parameters specified.
- * @config
- */
-private static final String PAR_METHOD = "method";
-
-
-// --------------------------------------------------------------------------
-// Fields
-// --------------------------------------------------------------------------
-
-/** Identifiers of the protocols to be initialized */
-private final int pid[];
-
-/** Method name */
-private final String methodName;
-
-/** Methods corresponding to the protocols in {@link #pid}. */
-private final Method method[];
-
-
-// --------------------------------------------------------------------------
-// Initialization
-// --------------------------------------------------------------------------
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param prefix the configuration prefix for this class
- */
-public MethodInvoker(String prefix) {
-
- methodName = Configuration.getString(prefix+"."+PAR_METHOD);
- if(!Configuration.contains(prefix+"."+PAR_PROT))
- {
- // find protocols that implement method
- ArrayList<Integer> pids = new ArrayList<Integer>();
- ArrayList<Method> methods = new ArrayList<Method>();
- for(int i=0; i<Network.prototype.protocolSize(); ++i)
- {
- Method m = null;
- try
- {
- m = MethodInvoker.getMethod(
- Network.prototype.getProtocol(i).getClass(),
- methodName );
- }
- catch(NoSuchMethodException e) {}
-
- if(m!=null)
- {
- pids.add(i);
- methods.add(m);
- }
- }
-
- if( pids.isEmpty() )
- {
- throw new IllegalParameterException(prefix + "." +
- PAR_METHOD,
- "No protocols found that implement 'void "+
- methodName+"()'");
- }
-
- pid=new int[pids.size()];
- int j=0;
- for(int i: pids) pid[j++]=i;
- method=methods.toArray(new Method[methods.size()]);
- }
- else
- {
- pid = new int[1];
- pid[0] = Configuration.getPid(prefix+"."+PAR_PROT);
- try
- {
- method = new Method[1];
- method[0]=MethodInvoker.getMethod(
- Network.prototype.getProtocol(pid[0]).getClass(),
- methodName );
- }
- catch (NoSuchMethodException e)
- {
- throw new IllegalParameterException(prefix + "." +
- PAR_METHOD, e+"");
- }
- }
-}
-
-// --------------------------------------------------------------------------
-// Methods
-// --------------------------------------------------------------------------
-
-private static Method getMethod(Class cl, String methodName)
-throws NoSuchMethodException {
-
- Method[] methods = cl.getMethods();
- ArrayList<Method> list = new ArrayList<Method>();
- for(Method m: methods)
- {
- if(m.getName().equals(methodName))
- {
- Class[] pars = m.getParameterTypes();
- Class ret = m.getReturnType();
- if( pars.length == 0 && ret==void.class )
- list.add(m);
- }
- }
-
- if(list.size() == 0)
- {
- throw new NoSuchMethodException("Method "
- + methodName + " in class " + cl.getName());
- }
-
- return list.get(0);
-}
-
-//--------------------------------------------------------------------------
-
-/** Invokes method on all the nodes. */
-public boolean execute() {
-
- for(int i=0; i<Network.size(); ++i)
- {
- initialize(Network.get(i));
- }
-
- return false;
-}
-
-//--------------------------------------------------------------------------
-
-/** Invokes method on given node. */
-public void initialize(Node n) {
-
- try
- {
- for(int i=0; i<pid.length; ++i)
- {
- CommonState.setNode(n);
- CommonState.setPid(pid[i]);
- method[i].invoke(n.getProtocol(pid[i]));
- }
- }
- catch(Exception e)
- {
- e.printStackTrace();
- System.exit(1);
- }
-}
-}
+++ /dev/null
-/*
- * 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.dynamics;
-
-import peersim.core.Node;
-
-/**
- * Generic interface to initialize a node before inserting it into the
- * simulation. Other components like {@link DynamicNetwork} can use a
- * NodeInitializer. It is designed to allow maximal flexibility therefore poses
- * virtually no restrictions on the implementation. It can even be used to
- * implement initializations that require global knowledge of the system.
- */
-public interface NodeInitializer
-{
-
-/**
- * Performs arbitrary initializations on the given node. It is guaranteed that
- * this is called <em>before</em> inserting the node into the network.
- */
-public void initialize(Node n);
-
-}
+++ /dev/null
-/*
- * 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.dynamics;
-
-import peersim.config.Configuration;
-import peersim.core.*;
-
-/**
- * Makes the network size oscillate.
- * The network size will be the function of time, parameterized by this
- * parameter. The size function is
- * <code>avg+sin(time*pi/{@value #PAR_PERIOD})*ampl</code> where
- * <code>avg=({@value #PAR_MAX}+{@value #PAR_MIN})/2</code> and
- * <code>ampl=({@value #PAR_MAX}-{@value #PAR_MIN})/2</code>.
- * This function is independent of how many times this class is executed, that
- * is, whenever it is executed, it takes the current time and sets the network
- * size accordingly.
- */
-public class OscillatingNetwork implements Control
-{
-
-//--------------------------------------------------------------------------
-//Parameters
-//--------------------------------------------------------------------------
-
-/**
- * Config parameter which gives the prefix of node initializers. An arbitrary
- * number of node initializers can be specified (Along with their parameters).
- * These will be applied
- * on the newly created nodes. The initializers are ordered according to
- * alphabetical order if their ID.
- * Example:
- * <pre>
-control.0 DynamicNetwork
-control.0.init.0 RandNI
-control.0.init.0.k 5
-control.0.init.0.protocol somelinkable
-...
- * </pre>
- * @config
- */
-private static final String PAR_INIT = "init";
-
-/**
- * Nodes are added until the size specified by this parameter is reached. The
- * network will never exceed this size as a result of this class.
- * If not set, there will be no limit on the size of the network.
- * @config
- */
-private static final String PAR_MAX = "maxsize";
-
-/**
- * Nodes are removed until the size specified by this parameter is reached. The
- * network will never go below this size as a result of this class.
- * Defaults to 0.
- * @config
- */
-private static final String PAR_MIN = "minsize";
-
-/**
- * Config parameter used to define the length of one period of the oscillation.
- * The network size will be the function of time, parameterized by this
- * parameter. The size function is
- * <code>avg+sin(time*pi/{@value #PAR_PERIOD})*ampl</code> where
- * <code>avg=({@value #PAR_MAX}+{@value #PAR_MIN})/2</code> and
- * <code>ampl=({@value #PAR_MAX}-{@value #PAR_MIN})/2</code>.
- * @config
- */
-private static final String PAR_PERIOD = "period";
-
-
-//--------------------------------------------------------------------------
-//Fields
-//--------------------------------------------------------------------------
-
-/** Period */
-private final int period;
-
-/** Maximum size */
-private final int minsize;
-
-/** Minimum size */
-private final int maxsize;
-
-/** New nodes initializers */
-private final NodeInitializer[] inits;
-
-
-//--------------------------------------------------------------------------
-// Initialization
-//--------------------------------------------------------------------------
-
-/**
- * Standard constructor that reads the configuration parameters. Invoked by the
- * simulation engine.
- * @param prefix
- * the configuration prefix for this class
- */
-public OscillatingNetwork(String prefix)
-{
-
- period = Configuration.getInt(prefix + "." + PAR_PERIOD);
- maxsize =
- Configuration.getInt(
- prefix + "." + PAR_MAX,
- Integer.MAX_VALUE);
- minsize = Configuration.getInt(prefix + "." + PAR_MIN, 0);
-
- Object[] tmp = Configuration.getInstanceArray(prefix + "." + PAR_INIT);
- inits = new NodeInitializer[tmp.length];
- for (int i = 0; i < tmp.length; ++i)
- {
- inits[i] = (NodeInitializer) tmp[i];
- }
-}
-
-//--------------------------------------------------------------------------
-// Methods
-//--------------------------------------------------------------------------
-
-/**
- * Adds n nodes to the network. Extending classes can implement any algorithm to
- * do that. The default algorithm adds the given number of nodes after calling
- * all the configured initializers on them.
- *
- * @param n
- * the number of nodes to add, must be non-negative.
- */
-protected void add(int n)
-{
- for (int i = 0; i < n; ++i) {
- Node newnode = (Node) Network.prototype.clone();
- for (int j = 0; j < inits.length; ++j) {
- inits[j].initialize(newnode);
- }
- Network.add(newnode);
- }
-}
-
-// ------------------------------------------------------------------
-
-/**
- * Removes n nodes from the network. Extending classes can implement any
- * algorithm to do that. The default algorithm removes <em>random</em>
- * nodes <em>permanently</em> simply by calling {@link Network#remove(int)}.
- * @param n the number of nodes to remove
- */
-protected void remove(int n)
-{
- for (int i = 0; i < n; ++i) {
- Network.remove(CommonState.r.nextInt(Network.size()));
- }
-}
-
-// ------------------------------------------------------------------
-
-/**
- * Takes the current time and sets the network size according to a periodic
- * function of time.
- * The size function is
- * <code>avg+sin(time*pi/{@value #PAR_PERIOD})*ampl</code> where
- * <code>avg=({@value #PAR_MAX}+{@value #PAR_MIN})/2</code> and
- * <code>ampl=({@value #PAR_MAX}-{@value #PAR_MIN})/2</code>.
- * Calls {@link #add(int)} or {@link #remove} depending on whether the size
- * needs to be increased or decreased to get the desired size.
- * @return always false
- */
-public boolean execute()
-{
- long time = CommonState.getTime();
- int amplitude = (maxsize - minsize) / 2;
- int newsize = (maxsize + minsize) / 2 +
- (int) (Math.sin(((double) time) / period * Math.PI) *
- amplitude);
- int diff = newsize - Network.size();
- if (diff < 0)
- remove(-diff);
- else
- add(diff);
-
- return false;
-}
-
-}
+++ /dev/null
-/*
- * 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.dynamics;
-
-import peersim.core.*;
-import peersim.config.Configuration;
-
-/**
- * Initializes the neighbor list of a node with random links.
- */
-public class RandNI implements NodeInitializer {
-
-
-//--------------------------------------------------------------------------
-//Parameters
-//--------------------------------------------------------------------------
-
-/**
- * The protocol to operate on.
- * @config
- */
-private static final String PAR_PROT = "protocol";
-
-/**
- * The number of samples (with replacement) to draw to initialize the
- * neighbor list of the node.
- * @config
- */
-private static final String PAR_DEGREE = "k";
-
-/**
- * If this config property is defined, method {@link Linkable#pack()} is
- * invoked on the specified protocol at the end of the wiring phase.
- * Default to false.
- * @config
- */
-private static final String PAR_PACK = "pack";
-
-//--------------------------------------------------------------------------
-//Fields
-//--------------------------------------------------------------------------
-
-/**
- * The protocol we want to wire
- */
-private final int pid;
-
-/**
- * The degree of the regular graph
- */
-private final int k;
-
-/**
- * If true, method pack() is invoked on the initialized protocol
- */
-private final boolean pack;
-
-
-//--------------------------------------------------------------------------
-//Initialization
-//--------------------------------------------------------------------------
-
-/**
- * Standard constructor that reads the configuration parameters. Invoked by the
- * simulation engine.
- * @param prefix the configuration prefix for this class
- */
-public RandNI(String prefix)
-{
- pid = Configuration.getPid(prefix + "." + PAR_PROT);
- k = Configuration.getInt(prefix + "." + PAR_DEGREE);
- pack = Configuration.contains(prefix + "." + PAR_PACK);
-}
-
-//--------------------------------------------------------------------------
-//Methods
-//--------------------------------------------------------------------------
-
-/**
- * Takes {@value #PAR_DEGREE} random samples with replacement from the nodes of
- * the overlay network. No loop edges are added.
- */
-public void initialize(Node n)
-{
- if (Network.size() == 0) return;
-
- Linkable linkable = (Linkable) n.getProtocol(pid);
- for (int j = 0; j < k; ++j)
- {
- int r = CommonState.r.nextInt(Network.size());
- linkable.addNeighbor(Network.get(r));
- }
-
- if (pack) linkable.pack();
-}
-
-}
-
+++ /dev/null
-/*
- * 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.dynamics;
-
-import peersim.core.*;
-import peersim.config.Configuration;
-
-/**
- * Initializes a node's neighbor list with a fixed center.
- */
-public class StarNI implements NodeInitializer {
-
-
-// ========================= fields =================================
-// ==================================================================
-
-
-/**
- * The protocol to operate on.
- * @config
- */
-private static final String PAR_PROT = "protocol";
-
-/**
- * If this config property is defined, method {@link Linkable#pack()} is
- * invoked on the specified protocol at the end of the wiring phase.
- * Default to false.
- * @config
- */
-private static final String PAR_PACK = "pack";
-
-/**
- * The protocol we want to wire
- */
-protected final int pid;
-
-/** If true, method pack() is invoked on the initialized protocol */
-protected final boolean pack;
-
-/**
- * Used as center: nodes will link to this node.
- */
-protected Node center = null;
-
-
-// ==================== initialization ==============================
-//===================================================================
-
-
-public StarNI(String prefix) {
-
- pid = Configuration.getPid(prefix+"."+PAR_PROT);
- pack = Configuration.contains(prefix+"."+PAR_PACK);
-}
-
-
-// ===================== public methods ==============================
-// ===================================================================
-
-
-/**
- * Adds a link to a fixed node, the center. This fixed node remains the same
- * throughout consecutive calls to this method. If the center fails in the
- * meantime, a new one is chosen so care should be taken. The center is the
- * first node that is not down (starting from node 0, 1, etc)
- * at the time of the first call to the function. When a new center needs to
- * be chosen (the current one is down), the new center is again the first
- * one which is up. If no nodes are up, the node with the last index is set
- * as center, and selection of a new center is always attempted when this
- * method is called again.
- */
-public void initialize(Node n) {
-
- if( Network.size() == 0 ) return;
-
- for(int i=0; (center==null || !center.isUp()) && i<Network.size(); ++i)
- center=Network.get(i);
-
- ((Linkable)n.getProtocol(pid)).addNeighbor(center);
-
- if(pack)
- {
- ((Linkable)n.getProtocol(pid)).pack();
- }
-}
-
-}
-
+++ /dev/null
-/*
- * 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.dynamics;
-
-import peersim.graph.*;
-import peersim.core.*;
-import peersim.config.*;
-import java.lang.reflect.*;
-import java.util.ArrayList;
-
-/**
- * Takes a {@link Linkable} protocol and adds connections using an arbitrary
- * method.
- * No connections are removed.
- * The connections are added by an arbitrary method that can be specified
- * in the configuration.
- * The properties the method has to fulfill are the following
- <ul>
- <li>It MUST be static</li>
- <li>It MUST have a first argument that can be assigned from a class
- that implements {@link Graph}.</li>
- <li>It MAY contain zero or more arguments following the first one.</li>
- <li>All the arguments after the first one MUST be of primitive type int,
- long or double, except
- the last one, which MAY be of type that can be assigned from
- <code>java.util.Random</code></li>
- </ul>
- The arguments are initialized using the configuration as follows.
- <ul>
- <li>The first argument is the {@link Graph} that is passed to
- {@link #wire}.</li>
- <li>The arguments after the first one (indexed as 1,2,etc) are initialized
- from configuration parameters of the form {@value #PAR_ARG}i, where i is the
- index.
- <li>If the last argument can be assigned from
- <code>java.util.Random</code> then it is initialized with
- {@link CommonState#r}, the central source of randomness for the
- simulator.</li>
- </ul>
- For example, the class {@link WireWS} can be emulated by configuring
- <pre>
- init.0 WireByMethod
- init.0.class GraphFactory
- init.0.method wireWS
- init.0.arg1 10
- init.0.arg2 0.1
- ...
- </pre>
- Note that the {@value #PAR_CLASS} parameter defaults to {@link GraphFactory},
- and {@value #PAR_METHOD} defaults to "wire".
- */
-public class WireByMethod extends WireGraph {
-
-//--------------------------------------------------------------------------
-//Parameters
-//--------------------------------------------------------------------------
-
-/**
- * The prefix for the configuration properties that describe parameters.
- * @config
- */
-private static final String PAR_ARG = "arg";
-
-/**
-* The class that has the method we want to use. Defaults to
-* {@link GraphFactory}.
-* @config
-*/
-private static final String PAR_CLASS = "class";
-
-/**
-* The name of the method for wiring the graph. Defaults to <code>wire</code>.
-* @config
-*/
-private static final String PAR_METHOD = "method";
-
-//--------------------------------------------------------------------------
-//Fields
-//--------------------------------------------------------------------------
-
-private final Object[] args;
-
-private final Method method;
-
-//--------------------------------------------------------------------------
-//Initialization
-//--------------------------------------------------------------------------
-
-/**
- * Loads configuration. It verifies the constraints defined
- * in {@link WireByMethod}.
- * @param prefix the configuration prefix for this class
- */
-public WireByMethod(String prefix)
-{
- super(prefix);
-
- // get the method
- try
- {
- final Class wire =
- Configuration.getClass(prefix + "." + PAR_CLASS,
- Class.forName("peersim.graph.GraphFactory"));
- method = WireByMethod.getMethod(
- wire,
- Configuration.getString(prefix+"."+PAR_METHOD,"wire"));
- }
- catch( Exception e )
- {
- throw new RuntimeException(e);
- }
-
- // set the constant args (those other than 0th)
- Class[] argt = method.getParameterTypes();
- args = new Object[argt.length];
- for(int i=1; i<args.length; ++i)
- {
-
- if( argt[i]==int.class )
- args[i]=Configuration.getInt(prefix+"."+PAR_ARG+i);
- else if( argt[i]==long.class )
- args[i]=Configuration.getLong(prefix+"."+PAR_ARG+i);
- else if( argt[i]==double.class )
- args[i]=Configuration.getDouble(prefix+"."+PAR_ARG+i);
- else if(i==args.length-1 && argt[i].isInstance(CommonState.r))
- args[i]=CommonState.r;
- else
- {
- // we should neve get here
- throw new RuntimeException("Unexpected error, please "+
- "report this problem to the peersim team");
- }
- }
-}
-
-//--------------------------------------------------------------------------
-
-/**
- * Search a wiring method in the specified class.
- * @param cl
- * the class where to find the method
- * @param methodName
- * the method to be searched
- * @return the requested method, if it fully conforms to the definition of
- * the wiring methods.
- */
-private static Method getMethod(Class cl, String methodName)
- throws NoSuchMethodException, ClassNotFoundException {
-
- // Search methods
- Method[] methods = cl.getMethods();
- ArrayList<Method> list = new ArrayList<Method>();
- for (Method m: methods) {
- if (m.getName().equals(methodName)) {
- list.add(m);
- }
- }
-
- if (list.size() == 0) {
- throw new NoSuchMethodException("No method "
- + methodName + " in class " + cl.getSimpleName());
- } else if (list.size() > 1) {
- throw new NoSuchMethodException("Multiple methods called "
- + methodName + " in class " + cl.getSimpleName());
- }
-
- // Found a single method with the right name; check if
- // it is a setter.
- final Class graphClass = Class.forName("peersim.graph.Graph");
- final Class randomClass = Class.forName("java.util.Random");
- Method method = list.get(0);
- Class[] pars = method.getParameterTypes();
- if( pars.length < 1 || !pars[0].isAssignableFrom(graphClass) )
- throw new NoSuchMethodException(method.getName() + " of class "
- + cl.getSimpleName() + " is not a valid graph wiring method,"+
- " it has to have peersim.graph.Graph as first argument type");
- for(int i=1; i<pars.length; ++i)
- if( !( pars[i]==int.class || pars[i]==long.class ||
- pars[i]==double.class ||
- (i==pars.length-1 && pars[i].isAssignableFrom(randomClass)) ) )
- throw new NoSuchMethodException(method.getName() +
- " of class "+ cl.getSimpleName()
- + " is not a valid graph wiring method");
-
- if(method.toString().indexOf("static")<0)
- throw new NoSuchMethodException(method.getName() +
- " of class "+ cl.getSimpleName()
- + " is not a valid graph wiring method; it is not static");
-
- return method;
-}
-
-
-//--------------------------------------------------------------------------
-//Methods
-//--------------------------------------------------------------------------
-
-/** Invokes the method passing g to it.*/
-public void wire(Graph g) {
-
- args[0]=g;
- try { method.invoke(null,args); }
- catch( Exception e ) { throw new RuntimeException(e); }
-}
-
-}
-
+++ /dev/null
-/*
- * 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.dynamics;
-
-
-import java.io.IOException;
-import java.io.FileReader;
-import java.io.LineNumberReader;
-import java.util.StringTokenizer;
-import peersim.graph.Graph;
-import peersim.core.*;
-import peersim.config.Configuration;
-
-/**
-* Takes a {@link Linkable} protocol and adds connections that are stored in a
-* file. Note that no
-* connections are removed, they are only added. So it can be used in
-* combination with other initializers.
-* The format of the file is as follows. Each line begins with a node ID
-* (IDs start from 0) followed by a list of neighbors, separated by whitespace.
-* All node IDs larger than the actual network size will be discarded, but
-* it does not trigger an error. Lines starting with a "#" character and
-* empty lines are ignored.
-*/
-public class WireFromFile extends WireGraph {
-
-
-// ========================= fields =================================
-// ==================================================================
-
-
-/**
-* The filename to load links from.
-* @config
-*/
-private static final String PAR_FILE = "file";
-
-/**
-* The number of neighbors to be read from the file. If unset, the default
-* behavior is to read all links in the file. If set, then the first k
-* neighbors will be read only.
-* @config
-*/
-private static final String PAR_K = "k";
-
-private final String file;
-
-private final int k;
-
-// ==================== initialization ==============================
-// ==================================================================
-
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param prefix the configuration prefix for this class
- */
-public WireFromFile(String prefix) {
-
- super(prefix);
- file = Configuration.getString(prefix+"."+PAR_FILE);
- k = Configuration.getInt(prefix + "." + PAR_K, Integer.MAX_VALUE);
-}
-
-
-// ===================== public methods ==============================
-// ===================================================================
-
-
-/**
-* Wires the graph from a file.
-* The format of the file is as follows. Each line begins with a node ID
-* (IDs start from 0) followed by a list of neighbors, separated by whitespace.
-* All node IDs larger than the actual network size will be discarded, but
-* it does not trigger an error. Lines starting with a "#" character and
-* empty lines are ignored.
-*/
-public void wire(Graph g) {
-try
-{
- FileReader fr = new FileReader(file);
- LineNumberReader lnr = new LineNumberReader(fr);
- String line;
- boolean wasOutOfRange=false;
- while((line=lnr.readLine()) != null)
- {
- if( line.startsWith("#") ) continue;
- StringTokenizer st = new StringTokenizer(line);
- if(!st.hasMoreTokens()) continue;
-
- final int from = Integer.parseInt(st.nextToken());
- if( from < 0 || from >= Network.size() )
- {
- wasOutOfRange = true;
- continue;
- }
-
- for(int i=0; i<k && st.hasMoreTokens(); ++i)
- {
- final int to = Integer.parseInt(st.nextToken());
- if( to < 0 || to >= Network.size() )
- wasOutOfRange = true;
- else
- g.setEdge(from,to);
- }
- }
-
- if( wasOutOfRange )
- System.err.println("WireFromFile warning: in "+file+" "+
- "some nodes were out of range and so ignored.");
- lnr.close();
-}
-catch( IOException e )
-{
- throw new RuntimeException(e);
-}
-}
-
-}
+++ /dev/null
-/*
- * 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.dynamics;
-
-import peersim.graph.Graph;
-import peersim.core.*;
-import peersim.config.Configuration;
-
-/**
- * This class is the superclass of classes that
- * takes a {@link Linkable} protocol or a graph and add edges that define a
- * certain topology.
- * Note that no connections are removed, they are only added. So it can be used
- * in combination with other initializers.
- */
-public abstract class WireGraph implements Control
-{
-
-// --------------------------------------------------------------------------
-// Parameters
-// --------------------------------------------------------------------------
-
-/**
- * The {@link Linkable} protocol to operate on. If it is not specified,
- * then operates on {@link #g}. If {@link #g} is null, {@link #execute} throws
- * an Exception. Note that if {@link #g} is set, it will be used irrespective
- * of the setting of the protocol in this field.
- * @config
- */
-private static final String PAR_PROT = "protocol";
-
-/**
- * If this config property is defined, method {@link Linkable#pack()} is
- * invoked on the specified protocol at the end of the wiring phase.
- * Default to false.
- * @config
- */
-private static final String PAR_PACK = "pack";
-
-/**
- * If set, the generated graph is undirected. In other words, for each link
- * (i,j) a link (j,i) will also be added. Defaults to false.
- * @config
- */
-private static final String PAR_UNDIR = "undir";
-
-/**
-* Alias for {@value #PAR_UNDIR}.
-* @config
-*/
-private static final String PAR_UNDIR_ALT = "undirected";
-
-// --------------------------------------------------------------------------
-// Fields
-// --------------------------------------------------------------------------
-
-/**
- * The protocol we want to wire. It is negative if no protocol was set
- * (in that case, a graph must be specified, see {@link #g}).
- */
-protected final int pid;
-
-/** If true, method pack() is invoked on the initialized protocol */
-private final boolean pack;
-
-/** If true, edges are added in an undirected fashion.*/
-public final boolean undir;
-
-/**
-* If set (not null), this is the graph to wire. If null, the current overlay
-* is wired each time {@link #execute} is called, as specified by {@value
-* #PAR_PROT}.
-*/
-public Graph g=null;
-
-// --------------------------------------------------------------------------
-// Initialization
-// --------------------------------------------------------------------------
-
-/**
- * Standard constructor that reads the configuration parameters. Normally
- * invoked by the simulation engine.
- * @param prefix
- * the configuration prefix for this class
- */
-protected WireGraph(String prefix) {
-
- if( Configuration.contains(prefix + "." + PAR_PROT) )
- pid = Configuration.getPid(prefix + "." + PAR_PROT);
- else
- pid = -10;
- pack = Configuration.contains(prefix + "." + PAR_PACK);
- undir = (Configuration.contains(prefix + "." + PAR_UNDIR) |
- Configuration.contains(prefix + "." + PAR_UNDIR_ALT));
-}
-
-
-//--------------------------------------------------------------------------
-//Public methods
-//--------------------------------------------------------------------------
-
-/**
-* Calls method {@link #wire} with the graph {@link #g},
-* or if null, on the overlay specified by the protocol given by config
-* parameter {@value #PAR_PROT}. If neither {@link #g}, nor {@value #PAR_PROT}
-* is set, throws a RuntimException.
-*/
-public final boolean execute() {
-
- Graph gr;
- if(g==null && pid==-10)
- {
- throw new RuntimeException(
- "Neither a protocol, nor a graph is specified.");
- }
- if(g==null) gr = new OverlayGraph(pid,!undir);
- else gr=g;
-
- if(gr.size()==0) return false;
- wire(gr);
-
- if( g==null && pack)
- {
- int size = Network.size();
- for (int i = 0; i < size; i++)
- {
- Linkable link =
- (Linkable) Network.get(i).getProtocol(pid);
- link.pack();
- }
- }
- return false;
-}
-
-//--------------------------------------------------------------------------
-
-/** The method that should wire (add edges to) the given graph. Has to
-* be implemented by extending classes */
-public abstract void wire(Graph g);
-
-}
-
+++ /dev/null
-/*
- * 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.dynamics;
-
-import peersim.graph.*;
-import peersim.core.*;
-import peersim.config.*;
-
-/**
- * Takes a {@link Linkable} protocol and adds random connections. Note that no
- * connections are removed, they are only added. So it can be used in
- * combination with other initializers.
- * @see GraphFactory#wireKOut
- */
-public class WireKOut extends WireGraph {
-
-//--------------------------------------------------------------------------
-//Parameters
-//--------------------------------------------------------------------------
-
-/**
- * The number of outgoing edges to generate from each node.
- * Passed to {@link GraphFactory#wireKOut}.
- * No loop edges are generated.
- * In the undirected case, the degree
- * of nodes will be on average almost twice as much because the incoming links
- * also become links out of each node.
- * @config
- */
-private static final String PAR_DEGREE = "k";
-
-//--------------------------------------------------------------------------
-//Fields
-//--------------------------------------------------------------------------
-
-/**
- * The number of outgoing edges to generate from each node.
- */
-private final int k;
-
-//--------------------------------------------------------------------------
-//Initialization
-//--------------------------------------------------------------------------
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param prefix the configuration prefix for this class
- */
-public WireKOut(String prefix)
-{
- super(prefix);
- k = Configuration.getInt(prefix + "." + PAR_DEGREE);
-}
-
-//--------------------------------------------------------------------------
-//Methods
-//--------------------------------------------------------------------------
-
-/** Calls {@link GraphFactory#wireKOut}. */
-public void wire(Graph g) {
-
- GraphFactory.wireKOut(g,k,CommonState.r);
-}
-
-}
+++ /dev/null
-/*
- * 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.dynamics;
-
-import peersim.graph.*;
-import peersim.config.*;
-
-/**
- * Takes a {@link peersim.core.Linkable} protocol and adds connections that
- * define a regular
- * rooted tree. Note that no
- * connections are removed, they are only added. So it can be used in
- * combination with other initializers.
- * @see #wire
- * @see GraphFactory#wireRegRootedTree
- */
-public class WireRegRootedTree extends WireGraph {
-
-//--------------------------------------------------------------------------
-//Parameters
-//--------------------------------------------------------------------------
-
-/**
- * The parameter of the tree wiring method.
- * It is passed to {@link GraphFactory#wireRegRootedTree}.
- * @config
- */
-private static final String PAR_DEGREE = "k";
-
-//--------------------------------------------------------------------------
-//Fields
-//--------------------------------------------------------------------------
-
-private final int k;
-
-//--------------------------------------------------------------------------
-//Initialization
-//--------------------------------------------------------------------------
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param prefix the configuration prefix for this class
- */
-public WireRegRootedTree(String prefix)
-{
- super(prefix);
- k = Configuration.getInt(prefix + "." + PAR_DEGREE);
-}
-
-//--------------------------------------------------------------------------
-//Methods
-//--------------------------------------------------------------------------
-
-/** Calls {@link GraphFactory#wireRegRootedTree}. */
-public void wire(Graph g) {
-
- GraphFactory.wireRegRootedTree(g,k);
-}
-
-}
+++ /dev/null
-/*
- * 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.dynamics;
-
-import peersim.graph.*;
-import peersim.config.Configuration;
-
-/**
- * Takes a {@link peersim.core.Linkable} protocol and adds edges that
- * define a ring lattice.
- * Note that no connections are removed, they are only added. So it can be used
- * in combination with other initializers.
- * @see GraphFactory#wireRingLattice
- */
-public class WireRingLattice extends WireGraph {
-
-// --------------------------------------------------------------------------
-// Parameters
-// --------------------------------------------------------------------------
-
-/**
- * The "lattice parameter" of the graph. The out-degree of the graph is equal to
- * 2k. See {@link GraphFactory#wireRingLattice} (to which this parameter is
- * passed) for further details.
- * @config
- */
-private static final String PAR_K = "k";
-
-// --------------------------------------------------------------------------
-// Fields
-// --------------------------------------------------------------------------
-
-/**
- */
-private final int k;
-
-// --------------------------------------------------------------------------
-// Initialization
-// --------------------------------------------------------------------------
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param prefix the configuration prefix for this class
- */
-public WireRingLattice(String prefix)
-{
- super(prefix);
- k = Configuration.getInt(prefix + "." + PAR_K);
-}
-
-//--------------------------------------------------------------------------
-//Public methods
-//--------------------------------------------------------------------------
-
-/** calls {@link GraphFactory#wireRingLattice}. */
-public void wire(Graph g)
-{
- GraphFactory.wireRingLattice(g, k);
-}
-
-//--------------------------------------------------------------------------
-
-}
+++ /dev/null
-/*
- * 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.dynamics;
-
-import peersim.config.*;
-import peersim.core.*;
-import peersim.graph.*;
-
-/**
-* This class contains the implementation of the Barabasi-Albert model
-* of growing scale free networks. The original model is described in
-* <a href="http://arxiv.org/abs/cond-mat/0106096">http://arxiv.org/abs/cond-mat/0106096</a>. It also contains the option of building
-* a directed network, in which case the model is a variation of the BA model
-* described in <a href="http://arxiv.org/pdf/cond-mat/0408391">
-http://arxiv.org/pdf/cond-mat/0408391</a>. In both cases, the number of the
-* initial set of nodes is the same as the degree parameter, and no links are
-* added. The first added node is connected to all of the initial nodes,
-* and after that the BA model is used normally.
-* @see GraphFactory#wireScaleFreeBA
-*/
-public class WireScaleFreeBA extends WireGraph {
-
-
-// ================ constants ============================================
-// =======================================================================
-
-/**
- * The number of edges added to each new node (apart from those forming the
- * initial network).
- * Passed to {@link GraphFactory#wireScaleFreeBA}.
- * @config
- */
-private static final String PAR_DEGREE = "k";
-
-
-// =================== fields ============================================
-// =======================================================================
-
-/** Parameter of the BA model. */
-private int k;
-
-// ===================== initialization ==================================
-// =======================================================================
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param prefix the configuration prefix for this class
-*/
-public WireScaleFreeBA(String prefix)
-{
- super(prefix);
- k = Configuration.getInt(prefix + "." + PAR_DEGREE);
-}
-
-
-// ======================== methods =======================================
-// ========================================================================
-
-
-/** calls {@link GraphFactory#wireScaleFreeBA}.*/
-public void wire(Graph g) {
-
- GraphFactory.wireScaleFreeBA(g,k,CommonState.r );
-}
-
-}
-
+++ /dev/null
-/*
- * 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.dynamics;
-
-import peersim.graph.Graph;
-import peersim.config.*;
-import peersim.core.*;
-
-/**
- * Wires a scale free graph using a method described in
- * <a href="http://xxx.lanl.gov/abs/cond-mat/0106144">this paper</a>.
- * It is an incremental technique, where the new nodes are connected to
- * the two ends of an edge that is already in the network.
- * This model always wires undirected links.
- */
-public class WireScaleFreeDM extends WireGraph {
-
-
-//--------------------------------------------------------------------------
-// Constants
-//--------------------------------------------------------------------------
-
-/**
- * The number of edges added to each new
- * node (apart from those forming the initial network) is twice this
- * value.
- * @config
- */
-private static final String PAR_EDGES = "k";
-
-
-//--------------------------------------------------------------------------
-// Fields
-//--------------------------------------------------------------------------
-
-
-/** The number of edges created for a new node is 2*k. */
-private final int k;
-
-
-//--------------------------------------------------------------------------
-// Constructor
-//--------------------------------------------------------------------------
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param prefix the configuration prefix for this class
- */
-public WireScaleFreeDM(String prefix)
-{
- super(prefix);
- k = Configuration.getInt(prefix + "." + PAR_EDGES);
-}
-
-
-//--------------------------------------------------------------------------
-// Methods
-//--------------------------------------------------------------------------
-
-/**
- * Wires a scale free graph using a method described in
- * <a href="http://xxx.lanl.gov/abs/cond-mat/0106144">this paper</a>.
- * It is an incremental technique, where the new nodes are connected to
- * the two ends of an edge that is already in the network.
- * This model always wires undirected links.
-*/
-public void wire(Graph g) {
-
- int nodes=g.size();
- int[] links = new int[4*k*nodes];
-
- // Initial number of nodes connected as a clique
- int clique = (k > 3 ? k : 3);
-
- // Add initial edges, to form a clique
- int len=0;
- for (int i=0; i < clique; i++)
- for (int j=0; j < clique; j++)
- {
- if (i != j)
- {
- g.setEdge(i,j);
- g.setEdge(j,i);
- links[len*2] = i;
- links[len*2+1] = j;
- len++;
- }
- }
-
- for (int i=clique; i < nodes; i++)
- for (int l=0; l < k; l++)
- {
- int edge = CommonState.r.nextInt(len);
- int m = links[edge*2];
- int j = links[edge*2+1];
- g.setEdge(i, m);
- g.setEdge(m, i);
- g.setEdge(j, m);
- g.setEdge(m, j);
- links[len*2] = i;
- links[len*2+1] = m;
- len++;
- links[len*2] = j;
- links[len*2+1] = m;
- len++;
- }
-}
-
-}
+++ /dev/null
-/*
- * 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.dynamics;
-
-import peersim.graph.*;
-
-/**
- * Takes a {@link peersim.core.Linkable} protocol and adds connection
- * which for a star
- * topology. No connections are removed, they are only added. So it can be used
- * in combination with other initializers.
- * @see GraphFactory#wireStar
- */
-public class WireStar extends WireGraph {
-
-// ===================== initialization ==============================
-// ===================================================================
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param prefix the configuration prefix for this class
- */
-public WireStar(String prefix) { super(prefix); }
-
-// ===================== public methods ==============================
-// ===================================================================
-
-
-/** Calls {@link GraphFactory#wireStar}.*/
-public void wire(Graph g) {
-
- GraphFactory.wireStar(g);
-}
-
-
-}
-
+++ /dev/null
-/*
- * 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.dynamics;
-
-import peersim.graph.*;
-import peersim.core.*;
-import peersim.config.Configuration;
-
-/**
-* Takes a {@link Linkable} protocol and adds connections following the
-* small-world model of Watts and Strogatz. Note that no
-* connections are removed, they are only added. So it can be used in
-* combination with other initializers.
-* @see GraphFactory#wireWS
-*/
-public class WireWS extends WireGraph {
-
-
-// ========================= fields =================================
-// ==================================================================
-
-/**
- * The beta parameter of a Watts-Strogatz graph represents the probability for a
- * node to be re-wired.
- * Passed to {@link GraphFactory#wireWS}.
- * @config
- */
-private static final String PAR_BETA = "beta";
-
-/**
- * The degree of the graph. See {@link GraphFactory#wireRingLattice}.
- * Passed to {@link GraphFactory#wireWS}.
- * @config
- */
-private static final String PAR_DEGREE = "k";
-
-/**
- * The degree of the regular graph
- */
-private final int k;
-
-/**
- * The degree of the regular graph
- */
-private final double beta;
-
-
-// ==================== initialization ==============================
-//===================================================================
-
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param prefix the configuration prefix for this class
- */
-public WireWS(String prefix) {
-
- super(prefix);
- k = Configuration.getInt(prefix+"."+PAR_DEGREE);
- beta = Configuration.getDouble(prefix+"."+PAR_BETA);
-}
-
-
-// ===================== public methods ==============================
-// ===================================================================
-
-
-/** calls {@link GraphFactory#wireWS}.*/
-public void wire(Graph g) {
-
- GraphFactory.wireWS(g,k,beta,CommonState.r);
-}
-
-}
-
+++ /dev/null
-/*
- * 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.edsim;
-
-import peersim.core.*;
-import peersim.cdsim.CDProtocol;
-import peersim.config.*;
-import peersim.dynamics.NodeInitializer;
-
-/**
- * Schedules the first execution of the cycle based protocol instances in the
- * event driven engine. It implements {@link Control} but it will most often be
- * invoked only once for each protocol as an initializer, since the scheduled
- * events schedule themselves for the consecutive executions (see
- * {@link NextCycleEvent}).
- *
- * <p>
- * All {@link CDProtocol} specifications in the configuration need to contain a
- * {@link Scheduler} specification at least for the step size (see config
- * parameter {@value peersim.core.Scheduler#PAR_STEP} of {@link Scheduler}).
- * This value is used as the cycle length for the corresponding protocol.
- *
- * @see NextCycleEvent
- */
-public class CDScheduler implements Control, NodeInitializer {
-
- // ============================== fields ==============================
- // ====================================================================
-
- /**
- * Parameter that is used to define the class that is used to schedule the
- * next cycle. Its type is (or extends) {@link NextCycleEvent}. Defaults to
- * {@link NextCycleEvent}.
- *
- * @config
- */
- private static final String PAR_NEXTC = "nextcycle";
-
- /**
- * The protocols that this scheduler schedules for the first execution. It
- * might contain several protocol names, separated by whitespace. All
- * protocols will be scheduled based on the common parameter set for this
- * scheduler and the parameters of the protocol (cycle length). Protocols
- * are scheduled independently of each other.
- *
- * @config
- */
- private static final String PAR_PROTOCOL = "protocol";
-
- /**
- * If set, it means that the initial execution of the given protocol is
- * scheduled for a different random time for all nodes. The random time is a
- * sample between the current time (inclusive) and the cycle length
- * (exclusive), the latter being specified by the step parameter (see
- * {@link Scheduler}) of the assigned protocol.
- *
- * @see #execute
- * @config
- */
- private static final String PAR_RNDSTART = "randstart";
-
- /**
- * Contains the scheduler objects for all {@link CDProtocol}s defined in the
- * configuration. The length of the array is the number of protocols
- * defined, but those entries that belong to protocols that are not
- * {@link CDProtocol}s are null.
- */
- public static final Scheduler[] sch;
-
- private final NextCycleEvent[] nce;
-
- private final int[] pid;
-
- private final boolean randstart;
-
- // =============================== initialization ======================
- // =====================================================================
-
- /**
- * Loads protocol schedulers for all protocols.
- */
- static {
-
- String[] names = Configuration.getNames(Node.PAR_PROT);
- sch = new Scheduler[names.length];
- for (int i = 0; i < names.length; ++i) {
- if (Network.prototype.getProtocol(i) instanceof CDProtocol)
- // with no default values for step to avoid
- // "overscheduling" due to lack of step option.
- sch[i] = new Scheduler(names[i], false);
- }
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Initialization based on configuration parameters.
- */
- public CDScheduler(String n) {
- String[] prots = Configuration.getString(n + "." + PAR_PROTOCOL).split("\\s");
- pid = new int[prots.length];
- nce = new NextCycleEvent[prots.length];
- for (int i = 0; i < prots.length; ++i) {
- pid[i] = Configuration.lookupPid(prots[i]);
- if (!(Network.prototype.getProtocol(pid[i]) instanceof CDProtocol)) {
- throw new IllegalParameterException(n + "." + PAR_PROTOCOL,
- "Only CDProtocols are accepted here");
- }
- nce[i] = (NextCycleEvent) Configuration.getInstance(n + "."
- + PAR_NEXTC, new NextCycleEvent(null));
- }
- randstart = Configuration.contains(n + "." + PAR_RNDSTART);
- }
-
- // ========================== methods ==================================
- // =====================================================================
-
- /**
- * Schedules the protocol at all nodes for the first execution adding it to
- * the priority queue of the event driven simulation. The time of the first
- * execution is determined by {@link #firstDelay}. The implementation calls
- * {@link #initialize} for all nodes.
- *
- * @see #initialize
- */
- public boolean execute() {
-
- for (int i = 0; i < Network.size(); ++i) {
- initialize(Network.get(i));
- }
-
- return false;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Schedules the protocol at given node for the first execution adding it to
- * the priority queue of the event driven simulation. The time of the first
- * execution is determined by a reference point in time and
- * {@link #firstDelay}, which defines the delay from the reference point.
- * The reference point is the maximum of the current time, and the value of
- * parameter {@value peersim.core.Scheduler#PAR_FROM} of the protocol being
- * scheduled. If the calculated time of the first execution is not valid
- * according to the schedule of the protocol then no execution is scheduled
- * for that protocol.
- * <p>
- * A final note: for performance reasons, the recommended practice is not to
- * use parameter {@value peersim.core.Scheduler#PAR_FROM} in protocols, but
- * to schedule {@link CDScheduler} itself for the desired time, whenever
- * possible (e.g., it is not possible if {@link CDScheduler} is used as a
- * {@link NodeInitializer}).
- */
- public void initialize(Node n) {
- /*
- * XXX If "from" is not the current time and this is used as a control
- * (not node initializer) then we dump _lots_ of events in the queue
- * that are just stored there until "from" comes. This reduces
- * performance, and should be fixed. When fixed, the final comment can
- * be removed from the docs.
- */
-
- final long time = CommonState.getTime();
- for (int i = 0; i < pid.length; ++i) {
- Object nceclone = null;
- try {
- nceclone = nce[i].clone();
- } catch (CloneNotSupportedException e) {
- } // cannot possibly happen
-
- final long delay = firstDelay(sch[pid[i]].step);
- final long nexttime = Math.max(time, sch[pid[i]].from) + delay;
- if (nexttime < sch[pid[i]].until)
- EDSimulator.add(nexttime - time, nceclone, n, pid[i]);
- }
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Returns the time (through giving the delay from the current time) when
- * this even is first executed. If {@value #PAR_RNDSTART} is not set, it
- * returns zero, otherwise a random value between 0, inclusive, and
- * cyclelength, exclusive.
- *
- * @param cyclelength
- * The cycle length of the cycle based protocol for which this
- * method is called
- */
- protected long firstDelay(long cyclelength) {
-
- if (randstart)
- return CommonState.r.nextLong(cyclelength);
- else
- return 0;
- }
-}
+++ /dev/null
-/*
- * 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.edsim;
-
-import peersim.core.Control;
-import peersim.core.Scheduler;
-
-
-/**
- * Wrapper for {@link Control}s to be executed in an event driven simulation.
- *
- * @author Alberto Montresor
- * @version $Revision: 1.5 $
- */
-class ControlEvent
-{
-
-//---------------------------------------------------------------------
-//Fields
-//---------------------------------------------------------------------
-
-/**
- * The reference to the dynamics to be executed; null if this cycle event
- * refers to an observer.
- */
-private Control control;
-
-/** Order index used to maintain order between cycle-based events */
-private int order;
-
-
-//---------------------------------------------------------------------
-//Initialization
-//---------------------------------------------------------------------
-
-/**
- * Scheduler object to obtain the next schedule time of this event
- */
-private Scheduler scheduler;
-
-/**
- * Creates a cycle event for a control object. It also schedules the object
- * for the first execution adding it to the priority queue of the event driven
- * simulation.
- */
-public ControlEvent(Control control, Scheduler scheduler, int order)
-{
- this.control = control;
- this.order = order;
- this.scheduler = scheduler;
- long next = scheduler.getNext();
- if( next>=0 ) EDSimulator.addControlEvent(next, order, this);
-}
-
-//---------------------------------------------------------------------
-//Methods
-//---------------------------------------------------------------------
-
-/**
-* Executes the control object, and schedules the object for the next execution
-* adding it to the priority queue of the event driven simulation.
-*/
-public boolean execute() {
-
- boolean ret = control.execute();
- long next = scheduler.getNext();
- if( next>=0 ) EDSimulator.addControlEvent(next, order, this);
- return ret;
-}
-
-}
-
-
+++ /dev/null
-/*
- * 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.edsim;
-
-import peersim.core.*;
-
-/**
- * The interface to be implemented by protocols run under the event-driven
- * model. A single method is provided, to deliver events to the protocol.
- *
- * @author Alberto Montresor
- * @version $Revision: 1.5 $
- */
-public interface EDProtocol
-extends Protocol
-{
-
- /**
- * This method is invoked by the scheduler to deliver events to the
- * protocol. Apart from the event object, information about the node
- * and the protocol identifier are also provided. Additional information
- * can be accessed through the {@link CommonState} class.
- *
- * @param node the local node
- * @param pid the identifier of this protocol
- * @param event the delivered event
- */
- public void processEvent( Node node, int pid, Object event );
-
-}
-
+++ /dev/null
-/*
- * 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.edsim;
-
-import java.util.Arrays;
-
-import peersim.Simulator;
-import peersim.config.*;
-import peersim.core.*;
-import psgsim.PSGSimulator;
-
-/**
- * Event-driven simulator engine. It is a fully static singleton class. For an
- * event driven simulation the configuration has to describe a set of
- * {@link Protocol}s, a set of {@link Control}s and their ordering and a set of
- * initializers and their ordering. See parameters {@value #PAR_INIT},
- * {@value #PAR_CTRL}.
- * <p>
- * One experiment run by {@link #nextExperiment} works as follows. First the
- * initializers are run in the specified order. Then the first execution of all
- * specified controls is scheduled in the event queue. This scheduling is
- * defined by the {@link Scheduler} parameters of each control component. After
- * this, the first event is taken from the event queue. If the event wraps a
- * control, the control is executed, otherwise the event is delivered to the
- * destination protocol, that must implement {@link EDProtocol}. This is
- * iterated while the current time is less than {@value #PAR_ENDTIME} or the
- * queue becomes empty. If more control events fall at the same time point, then
- * the order given in the configuration is respected. If more non-control events
- * fall at the same time point, they are processed in a random order.
- * <p>
- * The engine also provides the interface to add events to the queue. Note that
- * this engine does not explicitly run the protocols. In all cases at least one
- * control or initializer has to be defined that sends event(s) to protocols.
- * <p>
- * Controls can be scheduled (using the {@link Scheduler} parameters in the
- * configuration) to run after the experiment has finished. That is, each
- * experiment is finished by running the controls that are scheduled to be run
- * after the experiment.
- * <p>
- * Any control can interrupt an experiment at any time it is executed by
- * returning true in method {@link Control#execute}. However, the controls
- * scheduled to run after the experiment are still executed completely,
- * irrespective of their return value and even if the experiment was
- * interrupted.
- * <p>
- * {@link CDScheduler} has to be mentioned that is a control that can bridge the
- * gap between {@link peersim.cdsim} and the event driven engine. It can wrap
- * {@link peersim.cdsim.CDProtocol} appropriately so that the execution of the
- * cycles are scheduled in configurable ways for each node individually. In some
- * cases this can add a more fine-grained control and more realism to
- * {@link peersim.cdsim.CDProtocol} simulations, at the cost of some loss in
- * performance.
- * <p>
- * When protocols at different nodes send messages to each other, they might
- * want to use a model of the transport layer so that in the simulation message
- * delay and message omissions can be modeled in a modular way. This
- * functionality is implemented in package {@link peersim.transport}.
- *
- * @see Configuration
- */
-public class EDSimulator {
-
- // ---------------------------------------------------------------------
- // Parameters
- // ---------------------------------------------------------------------
-
- /**
- * The ending time for simulation. Only events that have a strictly smaller
- * value are executed. It must be positive. Although in principle negative
- * timestamps could be allowed, we assume time will be positive.
- *
- * @config
- */
- public static final String PAR_ENDTIME = "simulation.endtime";
-
- /**
- * This parameter specifies how often the simulator should log the current
- * time on the standard error. The time is logged only if there were events
- * in the respective interval, and only the time of some actual event is
- * printed. That is, the actual log is not guaranteed to happen in identical
- * intervals of time. It is merely a way of seeing whether the simulation
- * progresses and how fast...
- *
- * @config
- */
- private static final String PAR_LOGTIME = "simulation.logtime";
-
- /**
- * This parameter specifies the event queue to be used. It must be an
- * implementation of interface {@link PriorityQ}. If it is not defined, the
- * internal implementation is used.
- *
- * @config
- */
- private static final String PAR_PQ = "simulation.eventqueue";
-
- /**
- * This is the prefix for initializers. These have to be of type
- * {@link Control}. They are run at the beginning of each experiment, in the
- * order specified by the configuration.
- *
- * @see Configuration
- * @config
- * @config
- */
- private static final String PAR_INIT = "init";
-
- /**
- * This is the prefix for {@link Control} components. They are run at the
- * time points defined by the {@link Scheduler} associated to them. If some
- * controls have to be executed at the same time point, they are executed in
- * the order specified in the configuration.
- *
- * @see Configuration
- * @config
- */
- private static final String PAR_CTRL = "control";
-
- // ---------------------------------------------------------------------
- // Fields
- // ---------------------------------------------------------------------
-
- /** Maximum time for simulation */
- private static long endtime;
-
- /** Log time */
- private static long logtime;
-
- /** holds the modifiers of this simulation */
- private static Control[] controls = null;
-
- /** Holds the control schedulers of this simulation */
- private static Scheduler[] ctrlSchedules = null;
-
- /** Ordered list of events (heap) */
- private static PriorityQ heap = null;
-
- private static long nextlog = 0;
-
- // =============== initialization ======================================
- // =====================================================================
-
- /** to prevent construction */
- private EDSimulator() {
- }
-
- // ---------------------------------------------------------------------
- // Private methods
- // ---------------------------------------------------------------------
-
- /**
- * Load and run initializers.
- */
- private static void runInitializers() {
-
- Object[] inits = Configuration.getInstanceArray(PAR_INIT);
- String names[] = Configuration.getNames(PAR_INIT);
-
- for (int i = 0; i < inits.length; ++i) {
-
- System.err.println("- Running initializer " + names[i] + ": "
- + inits[i].getClass());
- ((Control) inits[i]).execute();
- }
- }
-
- // --------------------------------------------------------------------
-
- private static void scheduleControls() {
- // load controls
- String[] names = Configuration.getNames(PAR_CTRL);
- controls = new Control[names.length];
- ctrlSchedules = new Scheduler[names.length];
- for (int i = 0; i < names.length; ++i) {
- controls[i] = (Control) Configuration.getInstance(names[i]);
- ctrlSchedules[i] = new Scheduler(names[i], false);
- }
- System.err.println("EDSimulator: loaded controls "
- + Arrays.asList(names));
-
- // Schedule controls execution
- if (controls.length > heap.maxPriority() + 1)
- throw new IllegalArgumentException("Too many control objects");
- for (int i = 0; i < controls.length; i++) {
- new ControlEvent(controls[i], ctrlSchedules[i], i);
- }
- }
-
- // ---------------------------------------------------------------------
-
- /**
- * Adds a new event to be scheduled, specifying the number of time units of
- * delay, and the execution order parameter.
- *
- * @param time
- * The actual time at which the next event should be scheduled.
- * @param order
- * The index used to specify the order in which control events
- * should be executed, if they happen to be at the same time,
- * which is typically the case.
- * @param event
- * The control event
- */
- static void addControlEvent(long time, int order, ControlEvent event) {
- // we don't check whether time is negative or in the past: we trust
- // the caller, which must be from this package
- if (time >= endtime)
- return;
- heap.add(time, event, null, (byte) 0, order);
- }
-
- // ---------------------------------------------------------------------
-
- /**
- * This method is used to check whether the current configuration can be
- * used for event driven simulations. It checks for the existence of config
- * parameter {@value #PAR_ENDTIME}.
- */
- public static final boolean isConfigurationEventDriven() {
- return Configuration.contains(PAR_ENDTIME);
- }
-
- // ---------------------------------------------------------------------
-
- /**
- * Execute and remove the next event from the ordered event list.
- *
- * @return true if the execution should be stopped.
- */
- private static boolean executeNext() {
- PriorityQ.Event ev = heap.removeFirst();
- if (ev == null) {
- System.err.println("EDSimulator: queue is empty, quitting"
- + " at time " + CommonState.getTime());
- return true;
- }
-
- long time = ev.time;
-
- if (time >= nextlog) {
- // System.err.println("Current time: " + time);
- // seemingly complicated: to prevent overflow
- while (time - nextlog >= logtime)
- nextlog += logtime;
- if (endtime - nextlog >= logtime)
- nextlog += logtime;
- else
- nextlog = endtime;
- }
- if (time >= endtime) {
- System.err.println("EDSimulator: reached end time, quitting,"
- + " leaving " + heap.size()
- + " unprocessed events in the queue");
- return true;
- }
-
- CommonState.setTime(time);
- int pid = ev.pid;
- if (ev.node == null) {
- // might be control event; handled through a special method
- ControlEvent ctrl = null;
- try {
- ctrl = (ControlEvent) ev.event;
- } catch (ClassCastException e) {
- throw new RuntimeException(
- "No destination specified (null) for event " + ev);
- }
- return ctrl.execute();
- } else if (ev.node != Network.prototype && ev.node.isUp()) {
- CommonState.setPid(pid);
- CommonState.setNode(ev.node);
- if (ev.event instanceof NextCycleEvent) {
- NextCycleEvent nce = (NextCycleEvent) ev.event;
- nce.execute();
- } else {
- EDProtocol prot = null;
- try {
- prot = (EDProtocol) ev.node.getProtocol(pid);
- // System.out.println("prot "+prot.getClass().getName());
- } catch (ClassCastException e) {
- e.printStackTrace();
- throw new IllegalArgumentException("Protocol "
- + Configuration.lookupPid(pid)
- + " does not implement EDProtocol; "
- + ev.event.getClass());
- }
- prot.processEvent(ev.node, pid, ev.event);
- }
- }
-
- return false;
- }
-
- // ---------------------------------------------------------------------
- // Public methods
- // ---------------------------------------------------------------------
-
- /**
- * Runs an experiment, resetting everything except the random seed.
- */
- public static void nextExperiment() {
- // Reading parameter
- if (Configuration.contains(PAR_PQ))
- heap = (PriorityQ) Configuration.getInstance(PAR_PQ);
- else
- heap = new Heap();
- endtime = Configuration.getLong(PAR_ENDTIME);
- if (CommonState.getEndTime() < 0) // not initialized yet
- CommonState.setEndTime(endtime);
- if (heap.maxTime() < endtime)
- throw new IllegalParameterException(PAR_ENDTIME,
- "End time is too large: configured event queue only"
- + " supports " + heap.maxTime());
- logtime = Configuration.getLong(PAR_LOGTIME, Long.MAX_VALUE);
-
- // initialization
- System.err.println("EDSimulator: resetting");
- CommonState.setPhase(CommonState.PHASE_UNKNOWN);
- CommonState.setTime(0); // needed here
- controls = null;
- ctrlSchedules = null;
- nextlog = 0;
- Network.reset();
- System.err.println("EDSimulator: running initializers");
- runInitializers();
- scheduleControls();
- // Perform the actual simulation; executeNext() will tell when to
- // stop.
- boolean exit = false;
- while (!exit) {
- exit = executeNext();
- }
-
- // analysis after the simulation
- CommonState.setPhase(CommonState.POST_SIMULATION);
- for (int j = 0; j < controls.length; ++j) {
- if (ctrlSchedules[j].fin)
- controls[j].execute();
- }
-
- }
-
- // ---------------------------------------------------------------------
-
- /**
- * Adds a new event to be scheduled, specifying the number of time units of
- * delay, and the node and the protocol identifier to which the event will
- * be delivered.
- *
- * @param delay
- * The number of time units before the event is scheduled. Has to
- * be non-negative.
- * @param event
- * The object associated to this event
- * @param node
- * The node associated to the event.
- * @param pid
- * The identifier of the protocol to which the event will be
- * delivered
- */
- public static void add(long delay, Object event, Node node, int pid) {
- //if (event instanceof NextCycleEvent)
- //System.err.println("************* edsim delay="+delay +" pid="+pid+" event="+event+" time="+CommonState.getTime());
- if (Simulator.getSimID() == 2){
- PSGSimulator.add(delay, event, node, pid);
- }
-
- else {
- if (delay < 0)
- throw new IllegalArgumentException("Protocol "
- + node.getProtocol(pid) + " is trying to add event "
- + event + " with a negative delay: " + delay);
- if (pid > Byte.MAX_VALUE)
- throw new IllegalArgumentException(
- "This version does not support more than "
- + Byte.MAX_VALUE + " protocols");
-
- long time = CommonState.getTime();
- if (endtime - time > delay) // check like this to deal with overflow
- heap.add(time + delay, event, node, (byte) pid);
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2001 The Anthill Team
- *
- * 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.edsim;
-
-import peersim.core.Node;
-import peersim.core.CommonState;
-import peersim.config.Configuration;
-import peersim.config.IllegalParameterException;
-
-/**
- * The Heap data structure used to maintain events "sorted" by
- * scheduled time and to obtain the next event to be executed.
- *
- * @author Alberto Montresor
- * @version $Revision: 1.10 $
- */
-public class Heap implements PriorityQ {
-
-//--------------------------------------------------------------------------
-// Constants
-//--------------------------------------------------------------------------
-
-/**
- * This parameter specifies how many
- * bits are used to order events that occur at the same time. Defaults
- * to 8. A value smaller than 8 causes an IllegalParameterException.
- * Higher values allow for a better discrimination, but reduce
- * the maximal time steps that can be simulated.
- * @config
- */
-private static final String PAR_PBITS = "pbits";
-private static final String PAR_PBITS_LEGACY = "simulation.timebits";
-
-/**
- * Specifies the initial capacity of the heap. Defaults to 65536.
- * @config
- */
-private static final String PAR_SIZE = "size";
-
-
-//--------------------------------------------------------------------------
-// Fields
-//--------------------------------------------------------------------------
-
-// The following arrays are four heaps ordered by time. The alternative
-// approach (i.e. to store event objects) requires much more memory,
-// and based on some tests that I've done is not really much faster.
-
-/** Event component of the heap */
-private Object[] events;
-
-/** Time component of the heap */
-private long[] times;
-
-/** Node component of the heap */
-private Node[] nodes;
-
-/** Pid component of the heap */
-private byte[] pids;
-
-/** Number of elements */
-private int size;
-
-/** Singleton event object used to return (event, time, node, pid) tuples */
-private final Event ev = new Event();
-
-/** The number of bits reserved to order event with the same timestamp */
-private final int pbits;
-
-/** The mask to test whether the time value fits into the range we can
-represent */
-private final long overflowMask;
-
-//--------------------------------------------------------------------------
-// Contructor
-//--------------------------------------------------------------------------
-
-/**
- * Initializes a new heap using defaults.
- */
-public Heap() {
- this(""); // "" is not a valid prefix for a component
-}
-
-//--------------------------------------------------------------------------
-
-/**
- * Initializes a new heap using the configuration.
- */
-public Heap(String prefix) {
-
- int size = Configuration.getInt(prefix+"."+PAR_SIZE,65536);
-
- // some complex stuff to deal with legacy parameter names...
- if( !Configuration.contains(PAR_PBITS_LEGACY) )
- pbits = Configuration.getInt(prefix+"."+PAR_PBITS,8);
- else
- {
- pbits = Configuration.getInt(PAR_PBITS_LEGACY);
- if( Configuration.contains(prefix+"."+PAR_PBITS) )
- throw new IllegalParameterException(PAR_PBITS_LEGACY,
- "Your configuration file contains both "+
- prefix+"."+PAR_PBITS+ " and "+
- PAR_PBITS_LEGACY+"; please remove "+
- PAR_PBITS_LEGACY);
- }
-
- if (pbits < 8 || pbits >= 31) {
- throw new IllegalParameterException(prefix+"."+PAR_PBITS,
- "This parameter should be >= 8 or < 31");
- }
- overflowMask = ~maxTime();
- events = new Object[size];
- times = new long[size];
- nodes = new Node[size];
- pids = new byte[size];
-}
-
-//--------------------------------------------------------------------------
-// Methods
-//--------------------------------------------------------------------------
-
-/**
- * Returns the current number of events in the system.
- */
-public int size()
-{
- return size;
-}
-
-//--------------------------------------------------------------------------
-
-/**
- * Add a new event, to be scheduled at the specified time.
- *
- * @param time the time at which this event should be scheduled
- * @param event the object describing the event
- * @param node the node at which the event has to be delivered
- * @param pid the protocol that handles the event
- */
-public void add(long time, Object event, Node node, byte pid)
-{
- add(time,event,node,pid,CommonState.r.nextInt(1 << pbits));
-}
-
-//--------------------------------------------------------------------------
-
-/**
- * Add a new event, to be scheduled at the specified time.
- *
- * @param time the time at which this event should be scheduled
- * @param event the object describing the event
- * @param node the node at which the event has to be delivered
- * @param pid the protocol that handles the event
- */
-public void add(long time, Object event, Node node, byte pid, long priority)
-{
- if( (time&overflowMask) != 0 ) throw new
- IllegalArgumentException("Time overflow: time="+time);
-//XXX should we test priority overflow? How much does it cost?
-
- time = (time << pbits) | priority;
-
- size++;
- int pos = size;
- put(pos, time, event, node, pid);
- while (pos > 1 && getTime(pos / 2) > time) {
- swap(pos, pos / 2);
- pos = pos / 2;
- }
-}
-
-//--------------------------------------------------------------------------
-
-/**
- * Removes the first event in the heap and returns it.
- * Note that, to avoid garbage collection, a singleton instance of
- * the Event class is used. This means that data contained in the
- * returned event are overwritten when a new invocation of this
- * method is performed.
- * @return first event or null if size is zero
- */
-public Event removeFirst() {
-
- if(size==0) return null;
-
- ev.time = times[0] >> pbits;
- ev.event = events[0];
- ev.node = nodes[0];
- ev.pid = pids[0];
- swap(1, size);
- size--;
- minHeapify(1);
- return ev;
-}
-
-//--------------------------------------------------------------------------
-
-public long maxTime() { return Long.MAX_VALUE >> pbits; }
-
-//--------------------------------------------------------------------------
-
-public long maxPriority() { return (1L << pbits)-1; }
-
-//--------------------------------------------------------------------------
-
-/**
- * Prints the time values contained in the heap.
- */
-public String toString()
-{
- StringBuffer buffer = new StringBuffer();
- buffer.append("[Size: " + size + " Times: ");
- for (int i=1; i <= size; i++) {
- buffer.append(getTime(i)+",");
- }
- buffer.append("]");
- return buffer.toString();
-}
-
-
-//--------------------------------------------------------------------------
-// Private methods
-//--------------------------------------------------------------------------
-
-/**
- *
- */
-private void minHeapify(int index)
-{
- // The time to be placed of the current node
- long time = getTime(index);
- // Left, right children of the current index
- int l,r;
- // Their associated time
- long lt, rt;
- // The minimum time between val, lt, rt
- long mintime;
- // The index of the mininum time
- int minindex = index;
- do {
- index = minindex;
- mintime = time;
- l = index << 1;
- r = l + 1;
- if (l <= size && (lt = getTime(l)) < mintime) {
- minindex = l;
- mintime = lt;
- }
- if (r <= size && (rt = getTime(r)) < mintime) {
- minindex = r;
- mintime = rt;
- }
- if (minindex != index) {
- swap(minindex, index);
- }
- } while (minindex != index);
-}
-
-//--------------------------------------------------------------------------
-
-/**
- *
- */
-private void swap(int i1, int i2) {
-
- i1--;
- i2--;
-
- Object te = events[i1];
- events[i1] = events[i2];
- events[i2] = te;
-
- long tt = times[i1];
- times[i1] = times[i2];
- times[i2] = tt;
-
- Node tn = nodes[i1];
- nodes[i1] = nodes[i2];
- nodes[i2] = tn;
-
- byte tp = pids[i1];
- pids[i1] = pids[i2];
- pids[i2] = tp;
-}
-
-//--------------------------------------------------------------------------
-
-/**
- *
- */
-private long getTime(int index) {
- /* Compute first and second index, and return the value */
- index--;
- return times[index];
-}
-
-//--------------------------------------------------------------------------
-
-/**
- *
- */
-private void put(int index, long time, Object event, Node node, byte pid) {
-
- index--;
- if (index >= events.length) {
- doubleCapacity();
- }
- events[index] = event;
- times[index] = time;
- nodes[index] = node;
- pids[index] = pid;
-}
-
-//--------------------------------------------------------------------------
-
-/**
- *
- */
-private void doubleCapacity() {
- int oldsize = events.length;
- int newsize = oldsize*2;
- Object[] te = new Object[newsize];
- System.arraycopy(events, 0, te, 0, oldsize);
- events = te;
- long[] tt = new long[newsize];
- System.arraycopy(times, 0, tt, 0, oldsize);
- times = tt;
- Node[] tn = new Node[newsize];
- System.arraycopy(nodes, 0, tn, 0, oldsize);
- nodes = tn;
- byte[] tp = new byte[newsize];
- System.arraycopy(pids, 0, tp, 0, oldsize);
- pids = tp;
-}
-
-//--------------------------------------------------------------------------
-// Testing
-//--------------------------------------------------------------------------
-
-/*
-public static void main(String[] args) {
- Random random = new Random();
- Heap heap = new Heap();
- int rep = 1000000;
- if( args.length > 0 ) rep = Integer.parseInt(args[0]);
- int[] values1 = new int[rep];
- long[] values2 = new long[rep];
- for (int i = 0; i < rep; i++) {
- values1[i] = random.nextInt(1000000000);
- }
-
- long time1 = System.currentTimeMillis();
- for (int i = 0; i < rep; i++) {
- heap.add(values1[i], null, null, (byte) 1);
- }
- long time2 = System.currentTimeMillis();
- System.out.println("Inserting: " + (time2-time1));
-
- time1 = System.currentTimeMillis();
- for (int i = 0; i < rep; i++) {
- values2[i] = heap.removeFirst().time;
- }
- time2 = System.currentTimeMillis();
- System.out.println("Removing: " + (time2-time1));
-
- Arrays.sort(values1);
- for (int i=0; i<rep; i++) {
- if (values1[i] != values2[i])
- System.out.print("+");
- }
-}
-*/
-
-} // END Heap
+++ /dev/null
-/*
- * 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.edsim;
-
-import peersim.core.*;
-import peersim.cdsim.CDProtocol;
-
-/**
- * This class is used to wrap a {@link CDProtocol} instance into an event so
- * that it can be used in the event based simulation engine. This class is
- * responsible for calling {@link CDProtocol#nextCycle} and also to schedule the
- * consecutive cycle. In the configuration of an event driven simulation
- * {@link CDProtocol}s can be configured using {@link CDScheduler}, which places
- * appropriate instances of this events in the queue.
- *
- * <p>
- * Note that reimplementing method {@link #nextDelay} of this class allows for
- * arbitrary scheduling, including adaptively changing or irregular cycle
- * lengths, etc.
- *
- * @see CDScheduler
- * @see CDProtocol
- */
-public class NextCycleEvent implements Cloneable {
-
- // =============================== initialization ======================
- // =====================================================================
-
- /**
- * Reads configuration to initialize the object. Extending classes should
- * have a constructor with the same signature, often as simple as
- * <code>super(n)</code>.
- */
- public NextCycleEvent(String n) {
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Returns a clone of the object. Overriding this method is necessary and
- * typically is as simple as <code>return super.clone()</code>. In general,
- * always use <code>super.clone()</code> to obtain the object to be returned
- * on which you can perform optional deep cloning operations (arrays, etc).
- */
- public Object clone() throws CloneNotSupportedException {
-
- return super.clone();
- }
-
- // ========================== methods ==================================
- // =====================================================================
-
- /**
- * Executes the nextCycle method of the protocol, and schedules the next
- * call using the delay returned by {@link #nextDelay}. If the next
- * execution time as defined by the delay is outside of the valid times as
- * defined by {@link CDScheduler#sch}, then the next event is not scheduled.
- * Note that this means that this protocol will no longer be scheduled
- * because the next event after the next event is scheduled by the next
- * event.
- */
- public final void execute() {
-
- int pid = CommonState.getPid();
- Node node = CommonState.getNode();
- CDProtocol cdp = (CDProtocol) node.getProtocol(pid);
- cdp.nextCycle(node, pid);
- long delay = nextDelay(CDScheduler.sch[pid].step);
-
- if (CommonState.getTime() + delay < CDScheduler.sch[pid].until)
- EDSimulator.add(delay, this, node, pid);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Calculates the delay until the next execution of the protocol. This
- * default implementation returns a constant delay equal to the step
- * parameter (cycle length in this case) of the schedule of this event (as
- * set in the config file).
- */
- protected long nextDelay(long step) {
-
- return step;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c)2008 The Peersim Team
- *
- * 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.edsim;
-
-import peersim.core.Node;
-
-/**
- * The interface to be implemented by the event queue of the evend based
- * engine. An implementation must also provide the standard cosntructor
- * required by any peersim components: one that takes a String argument,
- * the component name in the configuration.
- */
-public interface PriorityQ {
-
-
-/**
- * Returns the current number of events in the queue.
- */
-public int size();
-
-/**
- * Add a new event, to be scheduled at the specified time. If there are other
- * events scheduled at the same time, then the time of execution if this event
- * relative to the other events is unspecified.
- *
- * @param time The time at which this event should be scheduled. It is
- * guaranteed to be non-negative (so no extra checks are needed)
- * @param event the object describing the event
- * @param node the node at which the event has to be delivered
- * @param pid the protocol that handles the event
- */
-public void add(long time, Object event, Node node, byte pid);
-
-/**
- * Add a new event, to be scheduled at the specified time, specifying also
- * the priority of the event, should there be other events scheduled at the
- * same time. If both time and priority is the same for an event, then the
- * scheduling order is unspecified.
- *
- * @param time The time at which this event should be scheduled. It is
- * guaranteed to be non-negative (so no extra checks are needed)
- * @param event the object describing the event
- * @param node the node at which the event has to be delivered
- * @param pid the protocol that handles the event
- * @param priority if for two events the "time" value is the same, this
- * value should be used to order them. Lower value means higher priority.
- * Like with time, non-negativity as assumed.
- */
-public void add(long time, Object event, Node node, byte pid, long priority);
-
-/**
- * Removes the first event in the heap and returns it.
- * The returned object is not guaranteed to be a freshly generated object,
- * that is, we allow for an implementation that keeps one copy of an event
- * object and always returns a reference to that copy.
- * @return first event or null if size is zero
- */
-public Event removeFirst();
-
-/**
-* Maximal value of time this interpretation can represent.
-*/
-public long maxTime();
-
-/**
-* Maximal value of priority this interpretation can deal with. That is,
-* the number of different priority levels is <tt>maxPriority()+1</tt> because
-* 0 is also a valid level.
-* @see #add(long,Object,Node,byte,long)
-*/
-public long maxPriority();
-
-/**
- * Return type of {@link #removeFirst()}.
- */
-public class Event
-{
- public Object event;
- public long time;
- public Node node;
- public byte pid;
- public String toString() {
- return event+" to node "+node+"prot "+pid+"at "+time; }
-}
-
-}
+++ /dev/null
-/*
- * 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.edsim;
-
-import peersim.core.*;
-
-
-/**
-* Implements random delay between calling the nextCycle method of the protocol.
-* @see #nextDelay
-*/
-public class RandNextCycle extends NextCycleEvent {
-
-
-// =============================== initialization ======================
-// =====================================================================
-
-
-/**
-* Calls super constructor.
-*/
-public RandNextCycle(String n) { super(n); }
-
-// --------------------------------------------------------------------
-
-/**
-* Calls super.clone().
-*/
-public Object clone() throws CloneNotSupportedException {
-
- return super.clone();
-}
-
-
-// ========================== methods ==================================
-// =====================================================================
-
-
-/**
-* Returns a random delay with uniform distribution between 1 (inclusive) and
-* 2*<code>step</code> (exclusive)
-* (expected value is therefore <code>step</code>).
-*/
-protected long nextDelay(long step) {
-
- return 1+CommonState.r.nextLong((step<<1)-1);
-}
-
-
-}
-
-
+++ /dev/null
-/*
- * 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.edsim;
-
-import peersim.core.*;
-
-
-/**
-* Implements a random delay, but making sure there is exactly one call in each
-* consecutive <code>step</code> time units.
-*/
-public class RegRandNextCycle extends NextCycleEvent {
-
-// ============================== fields ==============================
-// ====================================================================
-
-/**
-* Indicates the start of the next cycle for a particular protocol
-* instance. If negative it means it has not been initialized yet.
-*/
-private long nextCycleStart = -1;
-
-// =============================== initialization ======================
-// =====================================================================
-
-
-/**
-* Calls super constructor.
-*/
-public RegRandNextCycle(String n) {
-
- super(n);
-}
-
-// --------------------------------------------------------------------
-
-/**
-* Calls super.clone().
-*/
-public Object clone() throws CloneNotSupportedException {
-
- return super.clone();
-}
-
-
-// ========================== methods ==================================
-// =====================================================================
-
-
-/**
-* Returns a random delay but making sure there is exactly one invocation in each
-* consecutive interval of length <code>step</code>. The beginning of these
-* intervals is defined by the first invocation which is in turn defined by
-* {@link CDScheduler} that initiates the protocol in question.
-*/
-protected long nextDelay(long step) {
-
- // at this point nextCycleStart points to the start of the next cycle
- // (the cycle after the one in which this execution is taking place)
- // (note that the start of the cycle is included in the cycle)
-
- final long now = CommonState.getTime();
- if(nextCycleStart<0)
- {
- // not initialized
- nextCycleStart=now+step;
- }
-
- // to be on the safe side, we do the next while loop.
- // although currently it never executes
- while(nextCycleStart<=now) nextCycleStart+=step;
-
- // we increment nextCycleStart to point to the start of the cycle
- // after the next cycle
- nextCycleStart+=step;
-
- return nextCycleStart-now-CommonState.r.nextLong(step)-1;
-}
-
-}
-
-
+++ /dev/null
-<?xml version="1.0" encoding="ASCII"?>
-<jsp:Model xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:jsp="http://www.eclipse.org/MoDisco/JSP/0.1.incubation/jsp"/>
+++ /dev/null
-<?xml version="1.0" encoding="ASCII"?>
-<kdm:Segment xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:kdm="http://www.eclipse.org/MoDisco/kdm/kdm" xmlns:source="http://www.eclipse.org/MoDisco/kdm/source">
- <model xsi:type="source:InventoryModel" name="edsim">
- <inventoryElement xsi:type="source:Directory" name="edsim" path="/home/imb/Bureau/kbaati/pseclipse/work/PSG/src/peersim/edsim">
- <inventoryElement xsi:type="source:SourceFile" name="RandNextCycle.java" path="/home/imb/Bureau/kbaati/pseclipse/work/PSG/src/peersim/edsim/RandNextCycle.java"/>
- <inventoryElement xsi:type="source:SourceFile" name="RegRandNextCycle.java" path="/home/imb/Bureau/kbaati/pseclipse/work/PSG/src/peersim/edsim/RegRandNextCycle.java"/>
- <inventoryElement xsi:type="source:SourceFile" name="Heap.java" path="/home/imb/Bureau/kbaati/pseclipse/work/PSG/src/peersim/edsim/Heap.java"/>
- <inventoryElement xsi:type="source:SourceFile" name="ControlEvent.java" path="/home/imb/Bureau/kbaati/pseclipse/work/PSG/src/peersim/edsim/ControlEvent.java"/>
- <inventoryElement xsi:type="source:SourceFile" name="EDSimulator.java" path="/home/imb/Bureau/kbaati/pseclipse/work/PSG/src/peersim/edsim/EDSimulator.java"/>
- <inventoryElement xsi:type="source:SourceFile" name="CDScheduler.java" path="/home/imb/Bureau/kbaati/pseclipse/work/PSG/src/peersim/edsim/CDScheduler.java"/>
- <inventoryElement xsi:type="source:SourceFile" name="PriorityQ.java" path="/home/imb/Bureau/kbaati/pseclipse/work/PSG/src/peersim/edsim/PriorityQ.java"/>
- <inventoryElement xsi:type="source:SourceFile" name="NextCycleEvent.java" path="/home/imb/Bureau/kbaati/pseclipse/work/PSG/src/peersim/edsim/NextCycleEvent.java"/>
- <inventoryElement xsi:type="source:SourceFile" name="EDProtocol.java" path="/home/imb/Bureau/kbaati/pseclipse/work/PSG/src/peersim/edsim/EDProtocol.java"/>
- </inventoryElement>
- </model>
-</kdm:Segment>
+++ /dev/null
-/*
- * 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.graph;
-
-import java.util.*;
-
-/**
-* This class implements a graph which uses a bitmatrix as inner representation
-* of edges.
-*/
-public class BitMatrixGraph implements Graph {
-
-
-// ====================== private fileds ========================
-// ==============================================================
-
-private final List<BitSet> sets;
-
-private final boolean directed;
-
-// ====================== public constructors ===================
-// ==============================================================
-
-
-/**
-* Constructs a directed graph with the given number of nodes.
-* The graph has no edges initially. The graph is directed.
-* @param n size of graph
-*/
-public BitMatrixGraph( int n ) {
-
- this(n,true);
-}
-
-// ---------------------------------------------------------------
-
-/**
-* Constructs an graph with the given number of nodes.
-* The graph has no edges initially.
-* @param n size of graph
-* @param directed if true graph is directed
-*/
-public BitMatrixGraph( int n, boolean directed ) {
-
- sets = new ArrayList<BitSet>(n);
- for(int i=0; i<n; ++i) sets.add(new BitSet());
- this.directed = directed;
-}
-
-
-// ======================= Graph implementations ================
-// ==============================================================
-
-
-public boolean isEdge(int i, int j) {
-
- return sets.get(i).get(j);
-}
-
-// ---------------------------------------------------------------
-
-public Collection<Integer> getNeighbours(int i) {
-
- Set<Integer> result = new HashSet<Integer>();
- BitSet neighb = sets.get(i);
- final int max = size();
- for(int j=0; j<max; ++j)
- {
- if( neighb.get(j) ) result.add(j);
- }
-
- return Collections.unmodifiableCollection(result);
-}
-
-// ---------------------------------------------------------------
-
-/** Returns null always */
-public Object getNode(int i) { return null; }
-
-// ---------------------------------------------------------------
-
-/**
-* Returns null always.
-*/
-public Object getEdge(int i, int j) { return null; }
-
-// ---------------------------------------------------------------
-
-public int size() { return sets.size(); }
-
-// --------------------------------------------------------------------
-
-public boolean directed() { return directed; }
-
-// --------------------------------------------------------------------
-
-public boolean setEdge(int i, int j) {
-
- if( i > size() || j > size() || i<0 || j<0 ) throw new
- IndexOutOfBoundsException();
-
- BitSet neighb = sets.get(i);
- boolean old = neighb.get(j);
- neighb.set(j);
-
- if( !old && !directed )
- {
- neighb = sets.get(j);
- neighb.set(i);
- }
-
- return !old;
-}
-
-// --------------------------------------------------------------------
-
-public boolean clearEdge(int i, int j) {
-
- if( i > size() || j > size() || i<0 || j<0 ) throw new
- IndexOutOfBoundsException();
-
- BitSet neighb = sets.get(i);
- boolean old = neighb.get(j);
- neighb.clear(j);
-
- if( old && !directed )
- {
- neighb = sets.get(i);
- neighb.clear(j);
- }
-
- return old;
-}
-
-// --------------------------------------------------------------------
-
-public int degree(int i) {
-
- BitSet neighb = sets.get(i);
- return neighb.cardinality(); // only from jdk 1.4
-}
-
-}
-
+++ /dev/null
-/*
- * 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.graph;
-
-import java.util.*;
-
-/**
-* This class is an adaptor making any Graph an undirected graph
-* by making its edges bidirectional. The graph to be made undirected
-* is passed to the constructor. Only the reference is stored.
-* However, at construction time the incoming edges are stored
-* for each node, so if the graph
-* passed to the constructor changes over time then
-* methods {@link #getNeighbours(int)} and {@link #degree(int)}
-* become inconsistent (but only those).
-* The upside of this inconvenience is that {@link #getNeighbours} will have
-* constant time complexity.
-* @see UndirectedGraph
-*/
-public class ConstUndirGraph implements Graph {
-
-
-// ====================== private fileds ========================
-// ==============================================================
-
-
-protected final Graph g;
-
-protected final List<Integer>[] in;
-
-// ====================== public constructors ===================
-// ==============================================================
-
-/**
-* Initialization based on given graph. Stores the graph and if necessary
-* (if the graph is directed) searches for the incoming edges and stores
-* them too. The given graph is stored by reference (not cloned) so it should
-* not be modified while this object is in use.
-*/
-public ConstUndirGraph( Graph g ) {
-
- this.g = g;
- if( !g.directed() )
- {
- in = null;
- }
- else
- {
- in = new List[g.size()];
- }
-
- initGraph();
-}
-
-// --------------------------------------------------------------
-
-/** Finds and stores incoming edges */
-protected void initGraph() {
-
- final int max = g.size();
- for(int i=0; i<max; ++i) in[i] = new ArrayList<Integer>();
- for(int i=0; i<max; ++i)
- {
- for(Integer j:g.getNeighbours(i))
- {
- if( ! g.isEdge(j,i) ) in[j].add(i);
- }
- }
-}
-
-
-// ======================= Graph implementations ================
-// ==============================================================
-
-
-public boolean isEdge(int i, int j) {
-
- return g.isEdge(i,j) || g.isEdge(j,i);
-}
-
-// ---------------------------------------------------------------
-
-/**
-* Uses sets as collection so does not support multiple edges now, even if
-* the underlying directed graph does.
-*/
-public Collection<Integer> getNeighbours(int i) {
-
- List<Integer> result = new ArrayList<Integer>();
- result.addAll(g.getNeighbours(i));
- if( in != null ) result.addAll(in[i]);
- return Collections.unmodifiableCollection(result);
-}
-
-// ---------------------------------------------------------------
-
-/** Returns the node from the underlying graph */
-public Object getNode(int i) { return g.getNode(i); }
-
-// ---------------------------------------------------------------
-
-/**
-* If there is an (i,j) edge, returns that, otherwise if there is a (j,i)
-* edge, returns that, otherwise returns null.
-*/
-public Object getEdge(int i, int j) {
-
- if( g.isEdge(i,j) ) return g.getEdge(i,j);
- if( g.isEdge(j,i) ) return g.getEdge(j,i);
- return null;
-}
-
-// ---------------------------------------------------------------
-
-public int size() { return g.size(); }
-
-// --------------------------------------------------------------------
-
-public boolean directed() { return false; }
-
-// --------------------------------------------------------------------
-
-/** not supported */
-public boolean setEdge( int i, int j ) {
-
- throw new UnsupportedOperationException();
-}
-
-// ---------------------------------------------------------------
-
-/** not supported */
-public boolean clearEdge( int i, int j ) {
-
- throw new UnsupportedOperationException();
-}
-
-// ---------------------------------------------------------------
-
-public int degree(int i) { return g.degree(i)+(in==null?0:in[i].size()); }
-
-// ---------------------------------------------------------------
-/*
-public static void main( String[] args ) {
-
- Graph net = new BitMatrixGraph(20);
- GraphFactory.wireKOut(net,5,new Random());
- ConstUndirGraph ug = new ConstUndirGraph(net);
- for(int i=0; i<net.size(); ++i)
- System.err.println(
- i+" "+net.getNeighbours(i)+" "+net.degree(i));
- System.err.println("============");
- for(int i=0; i<ug.size(); ++i)
- System.err.println(i+" "+ug.getNeighbours(i)+" "+ug.degree(i));
- System.err.println("============");
- for(int i=0; i<ug.size(); ++i)
- System.err.println(i+" "+ug.in[i]);
- for(int i=0; i<ug.size(); ++i)
- {
- for(int j=0; j<ug.size(); ++j)
- System.err.print(ug.isEdge(i,j)?"W ":"+ ");
- System.err.println();
- }
-
- GraphIO.writeUCINET_DL(net,System.out);
- GraphIO.writeUCINET_DL(ug,System.out);
-}
-*/
-}
-
+++ /dev/null
-/*
- * 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.
- *
- */
-
-/*
- * Created on Jan 30, 2005 by Spyros Voulgaris
- *
- */
-package peersim.graph;
-
-import java.util.ArrayList;
-import java.util.BitSet;
-
-/**
-* Speeds up {@link ConstUndirGraph#isEdge} by storing the links in an
-* adjacency matrix (in fact in a triangle).
-* Its memory consumption is huge but it's much faster if the isEdge method
-* of the original underlying graph is slow.
-*/
-public class FastUndirGraph extends ConstUndirGraph
-{
-
-private BitSet[] triangle;
-
-
-// ======================= initializarion ==========================
-// =================================================================
-
-
-/** Calls super constructor */
-public FastUndirGraph(Graph graph)
-{
- super(graph);
-}
-
-// -----------------------------------------------------------------
-
-protected void initGraph()
-{
- final int max = g.size();
- triangle = new BitSet[max];
- for (int i=0; i<max; ++i)
- {
- in[i] = new ArrayList<Integer>();
- triangle[i] = new BitSet(i);
- }
-
- for(int i=0; i<max; ++i)
- {
- for(Integer out:g.getNeighbours(i))
- {
- int j=out.intValue();
- if( ! g.isEdge(j,i) )
- in[j].add(i);
- // But always add the link to the triangle
- if (i>j) // make sure i>j
- triangle[i].set(j);
- else
- triangle[j].set(i);
- }
- }
-}
-
-
-// ============================ Graph functions ====================
-// =================================================================
-
-
-public boolean isEdge(int i, int j)
-{
- // make sure i>j
- if (i<j)
- {
- int ii=i;
- i=j;
- j=ii;
- }
- return triangle[i].get(j);
-}
-}
-
+++ /dev/null
-/*
- * 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.graph;
-
-import java.util.Collection;
-
-/**
-* A general graph interface. It follows the following model:
-* the graph has n nodes which are indexed from 0 to n-1.
-* The parameters of operators refer to indices only.
-* Implementations might return objects that represent the
-* nodes or edges, although this is not required.
-*
-* Undirected graphs are modelled by the interface as directed graphs in which
-* every edge (i,j) has a corresponding reverse edge (j,i).
-*/
-public interface Graph {
-
- /**
- * Returns true if there is a directed edge between node i
- * and node j.
- */
- boolean isEdge(int i, int j);
-
- /**
- * Returns a collection view to all outgoing edges from
- * i. The collection should ideally be unmodifiable.
- * In any case, modifying the returned collection is not safe and
- * may result in unspecified behavior.
- */
- Collection<Integer> getNeighbours(int i);
-
- /**
- * Returns the node object associated with the index. Optional
- * operation.
- */
- Object getNode(int i);
-
- /**
- * Returns the edge object associated with the index. Optional
- * operation.
- */
- Object getEdge(int i, int j);
-
- /**
- * The number of nodes in the graph.
- */
- int size();
-
- /**
- * Returns true if the graph is directed otherwise false.
- */
- boolean directed();
-
- /**
- * Sets given edge, returns true if it did not exist before.
- * If the graph is
- * undirected, sets the edge (j,i) as well. Optional operation.
- */
- public boolean setEdge(int i, int j);
-
- /**
- * Removes given edge, returns true if it existed before. If the graph is
- * undirected, removes the edge (j,i) as well. Optional operation.
- */
- public boolean clearEdge(int i, int j);
-
- /**
- * Returns the degree of the given node. If the graph is directed,
- * returns out degree.
- */
- public int degree(int i);
-}
+++ /dev/null
-/*
- * 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.graph;
-
-import java.util.*;
-
-/**
-* Implements graph algorithms. The current implementation is NOT thread
-* safe. Some algorithms are not static, many times the result of an
-* algorithm can be read from non-static fields.
-*/
-public class GraphAlgorithms {
-
-// =================== public fields ==================================
-// ====================================================================
-
-/** output of some algorithms is passed here */
-public int[] root = null;
-private Stack<Integer> stack = new Stack<Integer>();
-private int counter=0;
-
-private Graph g=null;
-
-public final static int WHITE=0;
-public final static int GREY=1;
-public final static int BLACK=2;
-
-/** output of some algorithms is passed here */
-public int[] color = null;
-
-/** output of some algorithms is passed here */
-public Set<Integer> cluster = null;
-
-/** output of some algorithms is passed here */
-public int[] d = null;
-
-// =================== private methods ================================
-// ====================================================================
-
-
-/**
-* Collects nodes accessible from node "from" using depth-first search.
-* Works on the array {@link #color} which must be of the same length as
-* the size of the graph, and must contain values according to the
-* following semantics:
-* WHITE (0): not seen yet, GREY (1): currently worked upon. BLACK
-* (other than 0 or 1): finished.
-* If a negative color is met, it is saved in the {@link #cluster} set
-* and is treated as black. This can be used to check if the currently
-* visited cluster is weakly connected to another cluster.
-* On exit no nodes are GREY.
-* The result is the modified array {@link #color} and the modified set
-* {@link #cluster}.
-*/
-private void dfs( int from ) {
-
- color[from]=GREY;
-
- for(int j:g.getNeighbours(from))
- {
- if( color[j]==WHITE )
- {
- dfs(j);
- }
- else
- {
- if( color[j]<0 ) cluster.add(color[j]);
- }
- }
-
- color[from]=BLACK;
-}
-
-// --------------------------------------------------------------------
-
-/**
-* Collects nodes accessible from node "from" using breadth-first search.
-* Its parameters and side-effects are identical to those of dfs.
-* In addition, it stores the shortest distances from "from" in {@link #d},
-* if it is not null. On return, <code>d[i]</code> contains the length of
-* the shortest path from "from" to "i", if such a path exists, or it is
-* unchanged (ie the original value of <code>d[i]</code> is kept,
-* whatever that was.
-* <code>d</code> must either be long enough or null.
-*/
-private void bfs( int from ) {
-
- List<Integer> q = new LinkedList<Integer>();
- int u, du;
-
- q.add(from);
- q.add(0);
- if( d != null ) d[from] = 0;
-
- color[from]=GREY;
-
- while( ! q.isEmpty() )
- {
- u = q.remove(0).intValue();
- du = q.remove(0).intValue();
-
- for(int j:g.getNeighbours(u))
- {
- if( color[j]==WHITE )
- {
- color[j]=GREY;
-
- q.add(j);
- q.add(du+1);
- if( d != null ) d[j] = du+1;
- }
- else
- {
- if( color[j]<0 )
- cluster.add(color[j]);
- }
- }
- color[u]=BLACK;
- }
-}
-
-// --------------------------------------------------------------------
-
-/** The recursive part of the Tarjan algorithm. */
-private void tarjanVisit(int i) {
-
- color[i]=counter++;
- root[i]=i;
- stack.push(i);
-
- for(int j:g.getNeighbours(i))
- {
- if( color[j]==WHITE )
- {
- tarjanVisit(j);
- }
- if( color[j]>0 && color[root[j]]<color[root[i]] )
- // inComponent is false and have to update root
- {
- root[i]=root[j];
- }
- }
-
- int j;
- if(root[i]==i) //this node is the root of its cluster
- {
- do
- {
- j=stack.pop();
- color[j]=-color[j];
- root[j]=i;
- }
- while(j!=i);
- }
-}
-
-// =================== public methods ================================
-// ====================================================================
-
-/** Returns the weakly connected cluster indexes with size as a value.
-* Cluster membership can be seen from the content of the array {@link #color};
-* each node has the cluster index as color. The cluster indexes carry no
-* information; we guarantee only that different clusters have different indexes.
-*/
-public Map weaklyConnectedClusters( Graph g ) {
-
- this.g=g;
- if( cluster == null ) cluster = new HashSet<Integer>();
- if( color==null || color.length<g.size() ) color = new int[g.size()];
-
- // cluster numbers are negative integers
- int i, j, actCluster=0;
- for(i=0; i<g.size(); ++i) color[i]=WHITE;
- for(i=0; i<g.size(); ++i)
- {
- if( color[i]==WHITE )
- {
- cluster.clear();
- bfs(i); // dfs is recursive, for large graphs not ok
- --actCluster;
- for(j=0; j<g.size(); ++j)
- {
- if( color[j] == BLACK ||
- cluster.contains(color[j]) )
- color[j] = actCluster;
- }
- }
- }
-
- Hashtable<Integer,Integer> ht = new Hashtable<Integer,Integer>();
- for(j=0; j<g.size(); ++j)
- {
- Integer num = ht.get(color[j]);
- if( num == null ) ht.put(color[j],Integer.valueOf(1));
- else ht.put(color[j],num+1);
- }
-
- return ht;
-}
-
-// --------------------------------------------------------------------
-
-/**
-* In <code>{@link #d}[j]</code> returns the length of the shortest path between
-* i and j. The value -1 indicates that j is not accessible from i.
-*/
-public void dist( Graph g, int i ) {
-
- this.g=g;
- if( d==null || d.length<g.size() ) d = new int[g.size()];
- if( color==null || color.length<g.size() ) color = new int[g.size()];
-
- for(int j=0; j<g.size(); ++j)
- {
- color[j]=WHITE;
- d[j] = -1;
- }
-
- bfs(i);
-}
-
-// --------------------------------------------------------------------
-
-/**
-* Calculates the clustering coefficient for the given node in the given
-* graph. The clustering coefficient is the number of edges between
-* the neighbours of i divided by the number of possible edges.
-* If the graph is directed, an exception is thrown.
-* If the number of neighbours is 1, returns 1. For zero neighbours
-* returns NAN.
-* @throws IllegalArgumentException if g is directed
-*/
-public static double clustering( Graph g, int i ) {
-
- if( g.directed() ) throw new IllegalArgumentException(
- "graph is directed");
-
- Object[] n = g.getNeighbours(i).toArray();
-
- if( n.length==1 ) return 1.0;
-
- int edges = 0;
-
- for(int j=0; j<n.length; ++j)
- for(int k=j+1; k<n.length; ++k)
- if( g.isEdge((Integer)n[j],(Integer)n[k]) ) ++edges;
-
- return ((edges*2.0)/n.length)/(n.length-1);
-}
-
-// --------------------------------------------------------------------
-
-/**
-* Performs anti-entropy epidemic multicasting from node 0.
-* As a result the number of nodes that have been reached in cycle i
-* is put into <code>b[i]</code>.
-* The number of cycles performed is determined by <code>b.length</code>.
-* In each cycle each node contacts a random neighbour and exchanges
-* information. The simulation is generational: when a node contacts a neighbor
-* in cycle i, it sees their state as in cycle i-1, besides, all nodes update
-* their state at the same time point, synchronously.
-*/
-public static void multicast( Graph g, int[] b, Random r ) {
-
- int c1[] = new int[g.size()];
- int c2[] = new int[g.size()];
- for(int i=0; i<c1.length; ++i) c2[i]=c1[i]=WHITE;
- c2[0]=c1[0]=BLACK;
- Collection<Integer> neighbours=null;
- int black=1;
-
- int k=0;
- for(; k<b.length || black<g.size(); ++k)
- {
- for(int i=0; i<c2.length; ++i)
- {
- neighbours=g.getNeighbours(i);
- Iterator<Integer> it=neighbours.iterator();
- for(int j=r.nextInt(neighbours.size()); j>0; --j)
- it.next();
- int randn = it.next();
-
- // push pull exchane with random neighbour
- if( c1[i]==BLACK ) //c2[i] is black too
- {
- if(c2[randn]==WHITE) ++black;
- c2[randn]=BLACK;
- }
- else if( c1[randn]==BLACK )
- {
- if(c2[i]==WHITE) ++black;
- c2[i]=BLACK;
- }
- }
- System.arraycopy(c2,0,c1,0,c1.length);
- b[k]=black;
- }
-
- for(; k<b.length; ++k) b[k]=g.size();
-}
-
-// --------------------------------------------------------------------
-
-/**
-* Performs flooding from given node.
-* As a result <code>b[i]</code> contains the number of nodes
-* reached in exactly i steps, and always <code>b[0]=1</code>.
-* If the maximal distance from k is lower than <code>b.length</code>,
-* then the remaining elements of b are zero.
-*/
-public void flooding( Graph g, int[] b, int k ) {
-
- dist(g, k);
-
- for(int i=0; i<b.length; ++i) b[i]=0;
- for(int i=0; i<d.length; ++i)
- {
- if( d[i] >= 0 && d[i] < b.length ) b[d[i]]++;
- }
-}
-
-// --------------------------------------------------------------------
-
-/** Returns the strongly connected cluster roots with size as a value.
-* Cluster membership can be seen from the content of the array {@link #root};
-* each node has the root of the strongly connected cluster it belongs to.
-* A word of caution: for large graphs that have a large diameter and that
-* are strongly connected (such as large rings) you can get stack overflow
-* because of the large depth of recursion.
-*/
-//XXX implement a non-recursive version ASAP!!!
-public Map tarjan( Graph g ) {
-
- this.g=g;
- stack.clear();
- if( root==null || root.length<g.size() ) root = new int[g.size()];
- if( color==null || color.length<g.size() ) color = new int[g.size()];
- for( int i=0; i<g.size(); ++i) color[i]=WHITE;
- counter = 1;
-
- // color is WHITE (0): not visited
- // not WHITE, positive (c>1): visited as the c-th node
- // color is negative (c<1): inComponent true
- for(int i=0; i<g.size(); ++i)
- {
- if( color[i]==WHITE ) tarjanVisit(i);
- }
- for( int i=0; i<g.size(); ++i) color[i]=0;
- for( int i=0; i<g.size(); ++i) color[root[i]]++;
- Hashtable<Integer,Integer> ht = new Hashtable<Integer,Integer>();
- for(int j=0; j<g.size(); ++j)
- {
- if(color[j]>0)
- {
- ht.put(j,color[j]);
- }
- }
-
- return ht;
-}
-
-}
-
+++ /dev/null
-/*
- * 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.graph;
-
-import java.util.*;
-
-/**
-* Contains static methods for wiring certain kinds of graphs. The general
-* contract of all methods is that they accept any graph and add edges
-* as specified in the documentation.
-*/
-public class GraphFactory {
-
-/** Disable instance construction */
-private GraphFactory() {}
-
-// ===================== public static methods ======================
-// ==================================================================
-
-/**
-* Wires a ring lattice.
-* The added connections are defined as follows. If k is even, links to
-* i-k/2, i-k/2+1, ..., i+k/2 are added (but not to i), thus adding an
-* equal number of predecessors and successors.
-* If k is odd, then we add one more successors than predecessors.
-* For example, for k=4: 2 predecessors, 2 successors.
-* For k=5: 2 predecessors, 3 successors.
-* For k=1: each node is linked only to its successor.
-* All values are understood mod n to make the lattice circular, where n is the
-* number of nodes in g.
-* @param g the graph to be wired
-* @param k lattice parameter
-* @return returns g for convenience
-*/
-public static Graph wireRingLattice(Graph g, int k) {
-
- final int n = g.size();
-
- int pred = k/2;
- int succ = k-pred;
-
- for(int i=0; i<n; ++i)
- for(int j=-pred; j<=succ; ++j)
- {
- if( j==0 ) continue;
- final int v = (i+j+n)%n;
- g.setEdge(i,v);
- }
- return g;
-}
-
-// -------------------------------------------------------------------
-
-/**
-* Watts-Strogatz model. A bit modified though: by default assumes a directed
-* graph. This means that directed
-* links are re-wired, and the undirected edges in the original (undirected)
-* lattice are modeled
-* by double directed links pointing in opposite directions. Rewiring is done
-* with replacement, so the possibility of wiring two links to the same target
-* is positive (though very small).
-* <p>
-* Note that it is possible to pass an undirected graph as a parameter. In that
-* case the output is the directed graph produced by the method, converted to
-* an undirected graph by dropping directionality of the edges. This graph is
-* still not from the original undirected WS model though.
-* @param g the graph to be wired
-* @param k lattice parameter: this is the out-degree of a node in the
-* ring lattice before rewiring
-* @param p the probability of rewiring each
-* @param r source of randomness
-* @return returns g for convenience
-*/
-public static Graph wireWS( Graph g, int k, double p, Random r ) {
-//XXX unintuitive to call it WS due to the slight mods
- final int n = g.size();
- for(int i=0; i<n; ++i)
- for(int j=-k/2; j<=k/2; ++j)
- {
- if( j==0 ) continue;
- int newedge = (i+j+n)%n;
- if( r.nextDouble() < p )
- {
- newedge = r.nextInt(n-1);
- if( newedge >= i ) newedge++; // random _other_ node
- }
- g.setEdge(i,newedge);
- }
- return g;
-}
-
-// -------------------------------------------------------------------
-
-/**
-* Random graph. Generates randomly k directed edges out of each node.
-* The neighbors
-* (edge targets) are chosen randomly without replacement from the nodes of the
-* graph other than the source node (i.e. no loop edge is added).
-* If k is larger than N-1 (where N is the number of nodes) then k is set to
-* be N-1 and a complete graph is returned.
-* @param g the graph to be wired
-* @param k samples to be drawn for each node
-* @param r source of randomness
-* @return returns g for convenience
-*/
-public static Graph wireKOut( Graph g, int k, Random r ) {
-
- final int n = g.size();
- if( n < 2 ) return g;
- if( n <= k ) k=n-1;
- int[] nodes = new int[n];
- for(int i=0; i<nodes.length; ++i) nodes[i]=i;
- for(int i=0; i<n; ++i)
- {
- int j=0;
- while(j<k)
- {
- int newedge = j+r.nextInt(n-j);
- int tmp = nodes[j];
- nodes[j] = nodes[newedge];
- nodes[newedge] = tmp;
- if( nodes[j] != i )
- {
- g.setEdge(i,nodes[j]);
- j++;
- }
- }
- }
- return g;
-}
-
-// -------------------------------------------------------------------
-
-/**
-* A sink star.
-* Wires a sink star topology adding a link to 0 from all other nodes.
-* @param g the graph to be wired
-* @return returns g for convenience
-*/
-public static Graph wireStar( Graph g ) {
-
- final int n = g.size();
- for(int i=1; i<n; ++i) g.setEdge(i,0);
- return g;
-}
-
-// -------------------------------------------------------------------
-
-/**
-* A regular rooted tree.
-* Wires a regular rooted tree. The root is 0, it has links to 1,...,k.
-* In general, node i has links to i*k+1,...,i*k+k.
-* @param g the graph to be wired
-* @param k the number of outgoing links of nodes in the tree (except
-* leaves that have zero out-links, and exactly one node that might have
-* less than k).
-* @return returns g for convenience
-*/
-public static Graph wireRegRootedTree( Graph g, int k ) {
-
- if( k==0 ) return g;
- final int n = g.size();
- int i=0; // node we wire
- int j=1; // next free node to link to
- while(j<n)
- {
- for(int l=0; l<k && j<n; ++l,++j) g.setEdge(i,j);
- ++i;
- }
- return g;
-}
-
-// -------------------------------------------------------------------
-
-/**
-* A hypercube.
-* Wires a hypercube.
-* For a node i the following links are added: i xor 2^0, i xor 2^1, etc.
-* this define a log(graphsize) dimensional hypercube (if the log is an
-* integer).
-* @param g the graph to be wired
-* @return returns g for convenience
-*/
-public static Graph wireHypercube( Graph g ) {
-
- final int n = g.size();
- if(n<=1) return g;
- final int highestone = Integer.highestOneBit(n-1); // not zero
- for(int i=0; i<n; ++i)
- {
- int mask = highestone;
- while(mask>0)
- {
- int j = i^mask;
- if(j<n) g.setEdge(i,j);
- mask = mask >> 1;
- }
-
- }
- return g;
-}
-
-// -------------------------------------------------------------------
-
-/**
-* This contains the implementation of the Barabasi-Albert model
-* of growing scale free networks. The original model is described in
-* <a href="http://arxiv.org/abs/cond-mat/0106096">
-http://arxiv.org/abs/cond-mat/0106096</a>.
-* It also works if the graph is directed, in which case the model is a
-* variation of the BA model
-* described in <a href="http://arxiv.org/pdf/cond-mat/0408391">
-http://arxiv.org/pdf/cond-mat/0408391</a>. In both cases, the number of the
-* initial set of nodes is the same as the degree parameter, and no links are
-* added. The first added node is connected to all of the initial nodes,
-* and after that the BA model is used normally.
-* @param k the number of edges that are generated for each new node, also
-* the number of initial nodes (that have no edges).
-* @param r the randomness to be used
-* @return returns g for convenience
-*/
-public static Graph wireScaleFreeBA( Graph g, int k, Random r ) {
-
- final int nodes = g.size();
- if( nodes <= k ) return g;
-
- // edge i has ends (ends[2*i],ends[2*i+1])
- int[] ends = new int[2*k*(nodes-k)];
-
- // Add initial edges from k to 0,1,...,k-1
- for(int i=0; i < k; i++)
- {
- g.setEdge(k,i);
- ends[2*i]=k;
- ends[2*i+1]=i;
- }
-
- int len = 2*k; // edges drawn so far is len/2
- for(int i=k+1; i < nodes; i++) // over the remaining nodes
- {
- for (int j=0; j < k; j++) // over the new edges
- {
- int target;
- do
- {
- target = ends[r.nextInt(len)];
- int m=0;
- while( m<j && ends[len+2*m+1]!=target) ++m;
- if(m==j) break;
- // we don't check in the graph because
- // this wire method should accept graphs
- // that already have edges.
- }
- while(true);
- g.setEdge(i,target);
- ends[len+2*j]=i;
- ends[len+2*j+1]=target;
- }
- len += 2*k;
- }
-
- return g;
-}
-
-// -------------------------------------------------------------------
-/*
-public static void main(String[] pars) {
-
- int n = Integer.parseInt(pars[0]);
- //int k = Integer.parseInt(pars[1]);
- Graph g = new BitMatrixGraph(n);
-
- //wireWS(g,20,.1,new Random());
- //GraphIO.writeChaco(new UndirectedGraph(g),System.out);
-
- //wireScaleFreeBA(g,3,new Random());
- //wireKOut(g,k,new Random());
- //wireRegRootedTree(g,k);
- wireHypercube(g);
- GraphIO.writeNeighborList(g,System.out);
-}
-*/
-}
-
+++ /dev/null
-/*
- * 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.graph;
-
-import java.util.*;
-import java.io.*;
-
-/**
-* Implements static methods to load and write graphs.
-*/
-public class GraphIO {
-private GraphIO() {}
-
-
-// ================== public static methods =========================
-// ==================================================================
-
-
-/**
-* Prints graph in edge list format. Each line contains exactly two
-* node IDs separated by whitespace.
-*/
-public static void writeEdgeList( Graph g, PrintStream out ) {
-
- for(int i=0; i<g.size(); ++i)
- {
- Iterator it=g.getNeighbours(i).iterator();
- while(it.hasNext())
- {
- out.println(i+" "+it.next());
- }
- }
-}
-
-// ------------------------------------------------------------------
-
-/**
-* Prints graph in neighbor list format. Each line starts with the
-* id of a node followed by the ids of its neighbors separated by space.
-*/
-public static void writeNeighborList( Graph g, PrintStream out ) {
-
- out.println("# "+g.size());
-
- for(int i=0; i<g.size(); ++i)
- {
- out.print(i+" ");
- Iterator it=g.getNeighbours(i).iterator();
- while(it.hasNext())
- {
- out.print(it.next()+" ");
- }
- out.println();
- }
-}
-
-// ------------------------------------------------------------------
-
-/**
-* Saves the given graph to
-* the given stream in DOT format. Good for the graphviz package.
-*/
-public static void writeDOT( Graph g, PrintStream out ) {
-
- out.println((g.directed()?"digraph":"graph")+" {");
-
- for(int i=0; i<g.size(); ++i)
- {
- Iterator<Integer> it=g.getNeighbours(i).iterator();
- while(it.hasNext())
- {
- final int j = it.next();
- if(g.directed())
- out.println(i+" -> "+j+";");
- else if( i<=j )
- out.println(i+" -- "+j+";");
- }
- }
-
- out.println("}");
-}
-
-// ------------------------------------------------------------------
-
-/**
-* Saves the given graph to
-* the given stream in GML format.
-*/
-public static void writeGML( Graph g, PrintStream out ) {
-
- out.println("graph [ directed "+(g.directed()?"1":"0"));
-
- for(int i=0; i<g.size(); ++i)
- out.println("node [ id "+i+" ]");
-
- for(int i=0; i<g.size(); ++i)
- {
- Iterator it=g.getNeighbours(i).iterator();
- while(it.hasNext())
- {
- out.println(
- "edge [ source "+i+" target "+it.next()+" ]");
- }
- }
-
- out.println("]");
-}
-
-// --------------------------------------------------------------------
-
-/**
-* Saves the given graph to
-* the given stream to be read by NETMETER. It should be ok also for Pajek.
-*/
-public static void writeNetmeter( Graph g, PrintStream out ) {
-
- out.println("*Vertices "+g.size());
- for(int i=0; i<g.size(); ++i)
- out.println((i+1)+" \""+(i+1)+"\"");
-
- out.println("*Arcs");
- for(int i=0; i<g.size(); ++i)
- {
- Iterator it=g.getNeighbours(i).iterator();
- while(it.hasNext())
- {
- out.println((i+1)+" "+
- (((Integer)it.next()).intValue()+1)+" 1");
- }
- }
- out.println("*Edges");
-}
-
-// --------------------------------------------------------------------
-
-/**
-* Saves the given graph to
-* the given stream in UCINET DL nodelist format.
-*/
-public static void writeUCINET_DL( Graph g, PrintStream out ) {
-
- out.println("DL\nN="+g.size()+"\nFORMAT=NODELIST\nDATA:");
-
- for(int i=0; i<g.size(); ++i)
- {
- out.print(" " + (i+1));
- Iterator it=g.getNeighbours(i).iterator();
- while(it.hasNext())
- {
- out.print(" "+(((Integer)it.next()).intValue()+1));
- }
- out.println();
- }
- out.println();
-}
-
-// --------------------------------------------------------------------
-
-/**
-* Saves the given graph to
-* the given stream in UCINET DL matrix format.
-*/
-public static void writeUCINET_DLMatrix( Graph g, PrintStream out ) {
-
- out.println("DL\nN="+g.size()+"\nDATA:");
-
- for(int i=0; i<g.size(); ++i)
- {
- BitSet bs = new BitSet(g.size());
- Iterator it=g.getNeighbours(i).iterator();
- while(it.hasNext())
- {
- bs.set( ((Integer)it.next()).intValue() );
- }
- for(int j=0; j<g.size(); ++j)
- {
- out.print(bs.get(j)?" 1":" 0");
- }
- out.println();
- }
- out.println();
-}
-
-// --------------------------------------------------------------------
-
-/**
-* Saves the given graph to
-* the given stream in Chaco format. We need to output the number of edges
-* so they have to be counted first which might not be very efficient.
-* Note that this format is designed for undirected graphs only.
-*/
-public static void writeChaco( Graph g, PrintStream out ) {
-
- if( g.directed() ) System.err.println(
- "warning: you're saving a directed graph in Chaco format");
-
- long edges = 0;
- for(int i=0; i<g.size(); ++i) edges += g.getNeighbours(i).size();
-
- out.println( g.size() + " " + edges/2 );
-
- for(int i=0; i<g.size(); ++i)
- {
- Iterator it=g.getNeighbours(i).iterator();
- while(it.hasNext())
- {
- out.print((((Integer)it.next()).intValue()+1)+" ");
- }
- out.println();
- }
-
- out.println();
-}
-
-// -------------------------------------------------------------------
-
-/**
-* Read a graph in newscast graph format.
-* The format depends on mode, the parameter.
-* The file begins with the three byte latin 1 coded "NCG" string followed
-* by the int MODE which is the
-* given parameter. The formats are the following as a function of mode:
-* <ul>
-* <li> 1: Begins with cacheSize in binary format (int), followed by the
-* numberOfNodes (int), and then a continuous series of exactly
-* numberOfNodes records, where a record describes a node's
-* neighbours and their timestamps.
-* A record is a series of exactly cacheSize (int,long) pairs where
-* the int is the node id, and the long is the timestamp.
-* Node id-s start from 1. Node id 0 means no node and used if the parent
-* node has less that cacheSize nodes.</li>
-* </ul>
-* @param file Filename to read
-* @param direction If 0, the original directionality is preserved, if 1,
-* than each edge is reversed, if 2 then directionality is dropped and the
-* returned graph will be undirected.
-*/
-public static Graph readNewscastGraph( String file, int direction )
-throws IOException {
-
- NeighbourListGraph gr = new NeighbourListGraph( direction != 2 );
- FileInputStream fis = new FileInputStream(file);
- DataInputStream dis = new DataInputStream(fis);
-
- dis.readByte();
- dis.readByte();
- dis.readByte();
-
- final int MODE = dis.readInt();
- if( MODE != 1 ) throw new IOException("Unknown mode "+MODE);
-
- final int CACHESIZE = dis.readInt();
- final int GRAPHSIZE = dis.readInt();
-
-//System.out.println("header: "+MODE+" "+CACHESIZE+" "+GRAPHSIZE);
-
- for(int i=1; i<=GRAPHSIZE; ++i)
- {
- int iind = gr.addNode(i);
-
- for(int j=0; j<CACHESIZE; ++j)
- {
- int a = dis.readInt();
- dis.readLong();
-
- int agentIndex = gr.addNode(a);
- if( direction == 0 ) gr.setEdge(iind,agentIndex);
- else gr.setEdge(agentIndex,iind);
- }
- }
-
- dis.close();
-
- return gr;
-}
-
-
-}
-
+++ /dev/null
-/*
- * 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.graph;
-
-import java.util.*;
-
-/**
-* Implements a graph which uses the neighbour list representation.
-* No multiple edges are allowed. The implementation also supports the
-* growing of the graph. This is very useful when the number of nodes is
-* not known in advance or when we construct a graph reading a file.
-*/
-public class NeighbourListGraph implements Graph, java.io.Serializable {
-
-// =================== private fields ============================
-// ===============================================================
-
-/** Contains the objects associated with the node indeces.*/
-private final ArrayList<Object> nodes;
-
-/**
-* Contains the indices of the nodes. The vector "nodes" contains this
-* information implicitly but this way we can find indexes in log time at
-* the cost of memory (node that the edge lists typically use much more memory
-* than this anyway). Note that the nodes vector is still necessary to
-* provide constant access to nodes based on indexes.
-*/
-private final HashMap<Object,Integer> nodeindex;
-
-/** Contains sets of node indexes. If "nodes" is not null, indices are
-* defined by "nodes", otherwise they correspond to 0,1,... */
-private final ArrayList<Set<Integer>> neighbors;
-
-/** Indicates if the graph is directed. */
-private final boolean directed;
-
-// =================== public constructors ======================
-// ===============================================================
-
-/**
-* Constructs an empty graph. That is, the graph has zero nodes, but any
-* number of nodes and edges can be added later.
-* @param directed if true the graph will be directed
-*/
-public NeighbourListGraph( boolean directed ) {
-
- nodes = new ArrayList<Object>(1000);
- neighbors = new ArrayList<Set<Integer>>(1000);
- nodeindex = new HashMap<Object,Integer>(1000);
- this.directed = directed;
-}
-
-// ---------------------------------------------------------------
-
-/**
-* Constructs a graph with a fixed size without edges. If the graph is
-* constructed this way, it is not possible to associate objects to nodes,
-* nor it is possible to grow the graph using {@link #addNode}.
-* @param directed if true the graph will be directed
-*/
-public NeighbourListGraph( int size, boolean directed ) {
-
- nodes = null;
- neighbors = new ArrayList<Set<Integer>>(size);
- for(int i=0; i<size; ++i) neighbors.add(new HashSet<Integer>());
- nodeindex = null;
- this.directed = directed;
-}
-
-// =================== public methods =============================
-// ================================================================
-
-/**
-* If the given object is not associated with a node yet, adds a new
-* node. Returns the index of the node. If the graph was constructed to have
-* a specific size, it is not possible to add nodes and therefore calling
-* this method will throw an exception.
-* @throws NullPointerException if the size was specified at construction time.
-*/
-public int addNode( Object o ) {
-
- Integer index = nodeindex.get(o);
- if( index == null )
- {
- index = nodes.size();
- nodes.add(o);
- neighbors.add(new HashSet<Integer>());
- nodeindex.put(o,index);
- }
-
- return index;
-}
-
-
-// =================== graph implementations ======================
-// ================================================================
-
-
-public boolean setEdge( int i, int j ) {
-
- boolean ret = neighbors.get(i).add(j);
- if( ret && !directed ) neighbors.get(j).add(i);
- return ret;
-}
-
-// ---------------------------------------------------------------
-
-public boolean clearEdge( int i, int j ) {
-
- boolean ret = neighbors.get(i).remove(j);
- if( ret && !directed ) neighbors.get(j).remove(i);
- return ret;
-}
-
-// ---------------------------------------------------------------
-
-public boolean isEdge(int i, int j) {
-
- return neighbors.get(i).contains(j);
-}
-
-// ---------------------------------------------------------------
-
-public Collection<Integer> getNeighbours(int i) {
-
- return Collections.unmodifiableCollection(neighbors.get(i));
-}
-
-// ---------------------------------------------------------------
-
-/** If the graph was gradually grown using {@link #addNode}, returns the
-* object associated with the node, otherwise null */
-public Object getNode(int i) { return (nodes==null?null:nodes.get(i)); }
-
-// ---------------------------------------------------------------
-
-/**
-* Returns null always.
-*/
-public Object getEdge(int i, int j) { return null; }
-
-// ---------------------------------------------------------------
-
-public int size() { return neighbors.size(); }
-
-// --------------------------------------------------------------------
-
-public boolean directed() { return directed; }
-
-// --------------------------------------------------------------------
-
-public int degree(int i) { return neighbors.get(i).size(); }
-}
-
-
-
-
+++ /dev/null
-/*
- * 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.graph;
-
-import java.util.*;
-
-/**
-* This class is an adaptor for representing special subgraphs of any graph.
-* It can represent the subgraphs spanned by the nodes 0,...,i where
-* i is less than or equal to n-1, the last node of the original graph.
-* The underlying graph is stored by reference. This means that if the
-* graph changes, then these changes will be reflected by this class as well.
-* Besides, the size of the prefix can be changed at will at any time
-* using {@link #setSize}.
-*/
-public class PrefixSubGraph implements Graph {
-
-
-// ====================== private fileds ========================
-// ==============================================================
-
-
-private final Graph g;
-
-/** The graph represents the subgraph defined by nodes 0,...,prefSize */
-private int prefSize;
-
-
-// ====================== public constructors ===================
-// ==============================================================
-
-
-/**
-* Constructs an initially max size subgraph of g. That is, the subgraph will
-* contain all nodes.
-*/
-public PrefixSubGraph( Graph g ) {
-
- this.g = g;
- prefSize = g.size();
-}
-
-
-// ======================= Graph implementations ================
-// ==============================================================
-
-
-public boolean isEdge(int i, int j) {
-
- if( i<0 || i>=prefSize ) throw new IndexOutOfBoundsException();
- if( j<0 || j>=prefSize ) throw new IndexOutOfBoundsException();
- return g.isEdge(i,j);
-}
-
-// ---------------------------------------------------------------
-
-public Collection<Integer> getNeighbours(int i) {
-
- if( i<0 || i>=prefSize ) throw new IndexOutOfBoundsException();
-
- List<Integer> result = new LinkedList<Integer>();
- for(Integer j:g.getNeighbours(i))
- {
- if( j < prefSize ) result.add(j);
- }
-
- return Collections.unmodifiableCollection(result);
-}
-
-// ---------------------------------------------------------------
-
-public Object getNode(int i) {
-
- if( i<0 || i>=prefSize ) throw new IndexOutOfBoundsException();
- return g.getNode(i);
-}
-
-// ---------------------------------------------------------------
-
-/**
-* Returns the edge in the original graph if both i and j are smaller than
-* size().
-*/
-public Object getEdge(int i, int j) {
-
- if( isEdge(i,j) ) return g.getEdge(i,j);
- return null;
-}
-
-// --------------------------------------------------------------------
-
-public int size() { return prefSize; }
-
-// --------------------------------------------------------------------
-
-public boolean directed() { return g.directed(); }
-
-// --------------------------------------------------------------------
-
-/** not supported */
-public boolean setEdge( int i, int j ) {
-
- throw new UnsupportedOperationException();
-}
-
-// ---------------------------------------------------------------
-
-/** not supported */
-public boolean clearEdge( int i, int j ) {
-
- throw new UnsupportedOperationException();
-}
-
-// ---------------------------------------------------------------
-
-public int degree(int i) {
-
- if( i<0 || i>=prefSize ) throw new IndexOutOfBoundsException();
- return g.degree(i);
-}
-
-
-// ================= public functions =================================
-// ====================================================================
-
-
-/**
-* Sets the size of the subgraph. If i is negative, it is changed to 0 and
-* if it is larger than the underlying graph size, it is changed to the
-* underlying graph size (set at construction time).
-* @return old size.
-*/
-public int setSize(int i) {
-
- int was = prefSize;
- if( i < 0 ) i = 0;
- if( i > g.size() ) i=g.size();
- prefSize=i;
- return was;
-}
-}
-
+++ /dev/null
-/*
- * 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.graph;
-
-import java.util.*;
-
-/**
-* This class is an adaptor for representing subgraphs of any graph.
-* The subgraph is defined the following way.
-* The subgraph always contains all the nodes of the original underlying
-* graph. However, it is possible to remove edges by flagging nodes as
-* removed, in which case
-* the edges that have at least one end on those nodes are removed.
-* If the underlying graph changes after initialization, this class follows
-* the change.
-*/
-public class SubGraphEdges implements Graph {
-
-
-// ====================== private fields ========================
-// ==============================================================
-
-
-private final Graph g;
-
-private final BitSet nodes;
-
-
-// ====================== public constructors ===================
-// ==============================================================
-
-
-/**
-* Constructs an initially empty subgraph of g. That is, the subgraph will
-* contain no nodes.
-*/
-public SubGraphEdges( Graph g ) {
-
- this.g = g;
- nodes = new BitSet(g.size());
-}
-
-
-// ======================= Graph implementations ================
-// ==============================================================
-
-
-public boolean isEdge(int i, int j) {
-
- return nodes.get(i) && nodes.get(j) && g.isEdge(i,j);
-}
-
-// ---------------------------------------------------------------
-
-public Collection<Integer> getNeighbours(int i) {
-
- List<Integer> result = new LinkedList<Integer>();
- if( nodes.get(i) )
- {
- for(Integer in:g.getNeighbours(i))
- {
- if( nodes.get(in) ) result.add(in);
- }
- }
-
- return Collections.unmodifiableCollection(result);
-}
-
-// ---------------------------------------------------------------
-
-public Object getNode(int i) { return g.getNode(i); }
-
-// ---------------------------------------------------------------
-
-/**
-* If both i and j are within the node set of the subgraph and the original
-* graph has an (i,j) edge, returns that edge.
-*/
-public Object getEdge(int i, int j) {
-
- if( isEdge(i,j) ) return g.getEdge(i,j);
- return null;
-}
-
-// --------------------------------------------------------------------
-
-public int size() { return g.size(); }
-
-// --------------------------------------------------------------------
-
-public boolean directed() { return g.directed(); }
-
-// --------------------------------------------------------------------
-
-/** not supported */
-public boolean setEdge( int i, int j ) {
-
- throw new UnsupportedOperationException();
-}
-
-// ---------------------------------------------------------------
-
-/** not supported */
-public boolean clearEdge( int i, int j ) {
-
- throw new UnsupportedOperationException();
-}
-
-// ---------------------------------------------------------------
-
-public int degree(int i) {
-
- int degree=0;
- if( nodes.get(i) )
- {
- for(Integer in:g.getNeighbours(i))
- {
- if( nodes.get(in) ) degree++;
- }
- }
- return degree;
-}
-
-
-// ================= public functions =================================
-// ====================================================================
-
-
-/**
-* This function returns the size of the subgraph, i.e. the number of nodes
-* in the subgraph.
-*/
-public int subGraphSize() { return nodes.cardinality(); }
-
-// --------------------------------------------------------------------
-
-/**
-* Removes given node from subgraph.
-* @return true if the node was already in the subgraph otherwise false.
-*/
-public boolean removeNode(int i) {
-
- boolean was = nodes.get(i);
- nodes.clear(i);
- return was;
-}
-
-// --------------------------------------------------------------------
-
-/**
-* Adds given node to subgraph.
-* @return true if the node was already in the subgraph otherwise false.
-*/
-public boolean addNode(int i) {
-
- boolean was = nodes.get(i);
- nodes.set(i);
- return was;
-}
-}
-
+++ /dev/null
-/*
- * 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.graph;
-
-import java.util.*;
-
-/**
-* This class is an adaptor making any Graph an undirected graph
-* by making its edges bidirectional. The graph to be made undirected
-* is passed to the constructor. Only the reference is stored so
-* if the directed graph changes later, the undirected version will
-* follow that change. However, {@link #getNeighbours} has O(n) time complexity
-* (in other words, too slow for large graphs).
-* @see ConstUndirGraph
-*/
-public class UndirectedGraph implements Graph {
-
-
-// ====================== private fileds ========================
-// ==============================================================
-
-
-private final Graph g;
-
-
-// ====================== public constructors ===================
-// ==============================================================
-
-
-public UndirectedGraph( Graph g ) {
-
- this.g = g;
-}
-
-
-// ======================= Graph implementations ================
-// ==============================================================
-
-
-public boolean isEdge(int i, int j) {
-
- return g.isEdge(i,j) || g.isEdge(j,i);
-}
-
-// ---------------------------------------------------------------
-
-/**
-* Uses sets as collection so does not support multiple edges now, even if
-* the underlying directed graph does.
-*/
-public Collection<Integer> getNeighbours(int i) {
-
- Set<Integer> result = new HashSet<Integer>();
- result.addAll(g.getNeighbours(i));
- final int max = g.size();
- for(int j=0; j<max; ++j)
- {
- if( g.isEdge(j,i) ) result.add(j);
- }
-
- return Collections.unmodifiableCollection(result);
-}
-
-// ---------------------------------------------------------------
-
-public Object getNode(int i) { return g.getNode(i); }
-
-// ---------------------------------------------------------------
-
-/**
-* If there is an (i,j) edge, returns that, otherwise if there is a (j,i)
-* edge, returns that, otherwise returns null.
-*/
-public Object getEdge(int i, int j) {
-
- if( g.isEdge(i,j) ) return g.getEdge(i,j);
- if( g.isEdge(j,i) ) return g.getEdge(j,i);
- return null;
-}
-
-// ---------------------------------------------------------------
-
-public int size() { return g.size(); }
-
-// --------------------------------------------------------------------
-
-public boolean directed() { return false; }
-
-// --------------------------------------------------------------------
-
-/** not supported */
-public boolean setEdge( int i, int j ) {
-
- throw new UnsupportedOperationException();
-}
-
-// ---------------------------------------------------------------
-
-/** not supported */
-public boolean clearEdge( int i, int j ) {
-
- throw new UnsupportedOperationException();
-}
-
-// --------------------------------------------------------------------
-
-public int degree(int i) {
-
- return getNeighbours(i).size();
-}
-
-// --------------------------------------------------------------------
-/*
-public static void main( String[] args ) {
-
-
- Graph net = null;
- UndirectedGraph ug = new UndirectedGraph(net);
- for(int i=0; i<net.size(); ++i)
- System.err.println(i+" "+net.getNeighbours(i));
- System.err.println("============");
- for(int i=0; i<ug.size(); ++i)
- System.err.println(i+" "+ug.getNeighbours(i));
- for(int i=0; i<ug.size(); ++i)
- {
- for(int j=0; j<ug.size(); ++j)
- System.err.print(ug.isEdge(i,j)?"W ":"- ");
- System.err.println();
- }
-
- GraphIO.writeGML(net,System.out);
-}
-*/
-}
-
-
+++ /dev/null
-/*
- * 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.rangesim;
-
-public interface ProcessHandler
-{
-
-/**
- * Stop the external process managed by this object.
- */
-public abstract void doStop();
-
-/**
- * Wait until the process has terminated.
- * @exception InterruptedException
- * thrown if the wait is interrupted
- */
-public abstract void join()
- throws InterruptedException;
-
-}
\ No newline at end of file
+++ /dev/null
-package peersim.rangesim;
-
-import java.util.*;
-
-/**
- * This thread is used to kill forked processes in the case of an abnormal
- * termination of the Java virtual machine (for example, due to a signal).
- */
-public class ProcessManager extends Thread
-{
-
-/** The threads that must be killed */
-private List<ProcessHandler> threads;
-
-public ProcessManager()
-{
- threads = Collections.synchronizedList(new ArrayList<ProcessHandler>());
-}
-
-public void addThread(ProcessHandler p)
-{
- threads.add(p);
-}
-
-/**
- * Assumes that the process manager
- */
-public void joinAll()
-{
- int i=0;
- while (i < threads.size()) {
- try {
- threads.get(i).join();
- i++;
- } catch (InterruptedException e) {
- }
- }
-}
-
-
-/**
- * Kill the child process.
- */
-public void run()
-{
- System.err.println("Terminating simulation.");
- for (int i=0; i < threads.size(); i++) {
- if (threads.get(i) != null)
- threads.get(i).doStop();
- }
-}
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.rangesim;
-
-import java.io.*;
-import java.util.*;
-
-import peersim.*;
-import peersim.config.*;
-import peersim.core.*;
-import peersim.util.*;
-
-/**
- * This class is the main class for the Range Simulator. A range is
- * a collection of values <em>S</em> to be assigned to a variable
- * <em>v</em>. The Range Simulator invokes the standard Peersim
- * simulator once for each distinct value. If multiple ranges
- * <em>S1, S2, ..., Sn</em> are specified, the standard Peersim
- * simulator is invoked for each element in
- * <em>S1 * S2 * ... * Sn</em>.
- * <p>
- * Ranges are specified with the following syntax:
-<pre>
-range.[id] [var];[range]
-</pre>
- * where:
- * <UL>
- * <LI> {@value #PAR_RANGE} is the prefix for all range
- * specifications;</LI>
- * <LI> <code>id</code> is an identifier; since they are not referred anywhere else,
- * consecutive numbers are a good choice for range identifiers;</LI>
- * <LI> <code>var</code> is a variable parameter </LI>
- * <LI> <code>range</code> describes the collection of values to be associated
- * to <code>var</code>, whose syntax and semantics is defined in
- * {@link peersim.util.StringListParser}. </LI>
- * </UL>
- * Examples of range specifications are the following:
-<pre>
-range.0 SIZE;2^10:2^18|*2
-range.1 K;20:30
-range.2 CHURN;0.05,0.10,0.20
-</pre>
- * With this specification, the collection of values associated to
- * <code>SIZE</code> is {2^10,2^11,...,2^18}; <code>K</code> contains
- * {20,21,22,...,30}, while <code>CHURN</code> contains just the
- * specified values.
- * <p>
- * Values can be specified as constant expressions (like 2^10, (5+10), etc.)
- * but variables cannot be used.
- * <p>
- * A separate Java virtual machine is invoked to run each of the
- * experiments. An attempt is done to run the same JVM version as
- * the one running the Range Simulator; if this is not possible
- * (for example due to path problems), the command shell mechanism
- * is used to run the first JVM version found in the path.
- * </p>
- * It is possible to specify options for the forked JVM using the
- * {@value #PAR_JVM} parameter on the command line. For example,
- * a command line like this:
-<pre>
-java peersim.rangesim.RangeSimulator config.file jvm.options=-Xmx256m
-</pre>
- * can be used to run the forked JVM with a maximum heap of 256MB.
- * <p>
- * The new JVM inherits the same classpath as the JVM running the
- * RangeSimulator. The {@value #PAR_JVM} parameter can be used to
- * specify additional classpath specification.
- *
- * @author Alberto Montresor
- * @version $Revision: 1.11 $
- */
-public class RangeSimulator implements ProcessHandler
-{
-
-// --------------------------------------------------------------------------
-// Configuration parameters
-// --------------------------------------------------------------------------
-
-/**
- * This is the prefix of the config properties whose value vary during
- * a set of experiments.
- * @config
- */
-private static final String PAR_RANGE = "range";
-
-/**
- * This config property can be used to set options in the JVMs that
- * are forked to execute experiments with different configuration
- * parameters.
- * @config
- */
-public static final String PAR_JVM = "jvm.options";
-
-
-// --------------------------------------------------------------------------
-// Static variables
-// --------------------------------------------------------------------------
-
-/** Names of range parameters */
-private String[] pars;
-
-/** Values to be simulated, for each parameter */
-private String[][] values;
-
-/** The jvm options to be used when creating jvms */
-private String[] jvmoptions;
-
-/** Command line arguments */
-private String[] args;
-
-/** The current process that is executed */
-private Process p;
-
-
-// --------------------------------------------------------------------------
-// Main
-// --------------------------------------------------------------------------
-
-/**
- * Main method of the system.
- */
-public static void main(String[] args)
-{
- RangeSimulator r = new RangeSimulator(args);
- r.run();
-}
-
-//--------------------------------------------------------------------------
-// Constructor
-//--------------------------------------------------------------------------
-
-public RangeSimulator(String[] args)
-{
-
- // Check if there are no arguments or there is an explicit --help
- // flag; if so, print the usage of the class
- if (args.length == 0 || args[0].equals("--help")) {
- usage();
- System.exit(101);
- }
-
- this.args = args.clone();
-
- // Read property file
- System.err.println("Simulator: loading configuration");
- Properties properties = new ParsedProperties(args);
- Configuration.setConfig(properties);
-
- // Read jvm options and separate them in different strings
- String opt = Configuration.getString(PAR_JVM, null);
- if (opt == null)
- jvmoptions = new String[0];
- else
- jvmoptions = opt.split(" ");
-
- // Parse range parameters
- parseRanges();
-
-}
-
-/**
- * Main method to be executed
- */
-public void run()
-{
- // Shutdown thread management
- ProcessManager t = new ProcessManager();
- t.addThread(this);
- Runtime.getRuntime().addShutdownHook(t);
-
- // Executes experiments; report short messages about exceptions that are
- // handled by the configuration mechanism.
- try {
- doExperiments(args);
- } catch (MissingParameterException e) {
- Runtime.getRuntime().removeShutdownHook(t);
- System.err.println(e + "");
- System.exit(101);
- } catch (IllegalParameterException e) {
- Runtime.getRuntime().removeShutdownHook(t);
- System.err.println(e + "");
- System.exit(101);
- }
- Runtime.getRuntime().removeShutdownHook(t);
- System.exit(0);
-}
-
-// --------------------------------------------------------------------
-
-/**
- * Parses a collection of range specifications and returns the set of
- * parameter that will change during the simulation and the values that
- * will be used for those parameters.
- */
-private void parseRanges()
-{
- // Get ranges
- String[] ranges = Configuration.getNames(PAR_RANGE);
-
- // Start is the first element in which ranges are stored
- int start;
-
- // If there is an explicit simulation.experiment or there are no
- // ranges, put an experiment range at the beginning of the values.
- // Otherwise, just use the ranges.
- if (Configuration.contains(Simulator.PAR_EXPS) || ranges.length == 0) {
- pars = new String[ranges.length + 1];
- values = new String[ranges.length + 1][];
- pars[0] = "EXP";
- values[0] = StringListParser.parseList("1:"
- + Configuration.getInt(Simulator.PAR_EXPS, 1));
- start = 1;
- } else {
- pars = new String[ranges.length];
- values = new String[ranges.length][];
- start = 0;
- }
-
- for (int i = start; i < pars.length; i++) {
- String[] array = Configuration.getString(ranges[i-start]).split(";");
- if (array.length != 2) {
- throw new IllegalParameterException(ranges[i],
- " should be formatted as <parameter>;<value list>");
- }
- pars[i] = array[0];
- values[i] = StringListParser.parseList(array[1]);
- }
-}
-
-// --------------------------------------------------------------------
-
-/**
- * Selects the next set of values by incrementing the specified index
- * array. The index array is treated as a vector of digits; the first is
- * managed managed as a vector of digits.
- */
-private void nextValues(int[] idx, String[][] values)
-{
- idx[idx.length - 1]++;
- for (int j = idx.length - 1; j > 0; j--) {
- if (idx[j] == values[j].length) {
- idx[j] = 0;
- idx[j - 1]++;
- }
- }
-}
-
-// --------------------------------------------------------------------
-
-private void doExperiments(String[] args)
-{
-
- // Configure the java parameter for exception
- String filesep = System.getProperty("file.separator");
- String classpath = System.getProperty("java.class.path");
- String javapath = System.getProperty("java.home") + filesep + "bin" + filesep
- + "java";
- ArrayList<String> list = new ArrayList<String>(20);
- list.add(javapath);
- list.add("-cp");
- list.add(classpath);
-
- // Add the jvm options
- for (int i=0; i < jvmoptions.length; i++)
- list.add(jvmoptions[i]);
-
- // The class to be run in the forked JVM
- list.add("peersim.Simulator");
-
- // Parameters specified on the command line
- for (int i=0; i < args.length; i++) {
- list.add(args[i]);
- }
-
- // Since multiple experiments are managed here, the value
- // of standard variable for multiple experiments is changed to 1
- list.add(Simulator.PAR_EXPS+"=1");
-
- // Activate redirection to separate stdout from stderr
- list.add(Simulator.PAR_REDIRECT+"="+TaggedOutputStream.class.getCanonicalName());
- int startlog = list.size();
- list.add("");
-
- // Create a placeholder for the seed
- int startseed = list.size();
- list.add("");
-
- // Create placeholders for the range parameters
- int startpar = list.size();
- for (int i=0; i < values.length; i++)
- list.add("");
-
- // Execute with different values
- int[] idx = new int[values.length]; // Initialized to 0
- while (idx[0] < values[0].length) {
-
- // Configure the argument string array
- for (int j = 0; j < pars.length; j++) {
- list.set(startpar + j, pars[j] + "=" + values[j][idx[j]]);
- }
-
- // Fill the log placeholder
- StringBuffer log = new StringBuffer();
- for (int j = 0; j < pars.length; j++) {
- log.append(pars[j]);
- log.append(" ");
- log.append(values[j][idx[j]]);
- log.append(" ");
- }
- list.set(startlog, Simulator.PAR_REDIRECT+"."+
- TaggedOutputStream.PAR_RANGES+"="+log);
-
- // Fill the seed place holder
- long seed = CommonState.r.nextLong();
- list.set(startseed, CommonState.PAR_SEED+"="+seed);
-
- System.err.println("Experiment: " + log);
-
- executeProcess(list);
-
- // Increment values
- nextValues(idx, values);
-
- }
-}
-
-//--------------------------------------------------------------------
-
-/**
- * Execute the "command line" represented by this String list.
- * The first argument is the process to be executed. We try
- * to run the same JVM as the current one. If not possible,
- * we use the first java command found in the path.
- */
-private void executeProcess(List<String> list)
-{
- // Prepare the argument array for process forking
- String[] newargs = new String[list.size()];
-
- // Execute a new JVM
- try {
- ProcessBuilder pb = new ProcessBuilder(list.toArray(newargs));
- pb.redirectErrorStream(true);
- p = pb.start();
- } catch (IOException e1) {
- try {
- list.set(0, "java");
- ProcessBuilder pb = new ProcessBuilder(list.toArray(newargs));
- pb.redirectErrorStream(true);
- p = pb.start();
- } catch (IOException e2) {
- System.err.println("Unable to launch a Java virtual machine");
- System.exit(1);
- }
- }
-
- // Read the output from the process and redirect it to System.out
- // and System.err.
- BufferedReader toprint = new BufferedReader(new InputStreamReader(p
- .getInputStream()));
- String line;
- while ((line = getLine(toprint)) != null) {
- if (line.length() == 0) {
- System.out.println();
- } else {
- int last = line.charAt(line.length()-1);
- if (last != TaggedOutputStream.TAG) {
- System.err.println(line);
- } else {
- line = line.substring(0, line.length()-1);
- System.out.println(line);
- }
- }
- }
-
- // We close all the files and we destroy the process. They are not
- // cleaned when the process is closed. See:
- // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4784692
- // http://www.thescripts.com/forum/thread18019.html
- try {
- p.getErrorStream().close();
- p.getInputStream().close();
- p.getOutputStream().close();
- p.destroy();
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- // The static variable p (used also by ShutdownThread) is back to
- // null - no process must be killed on shutdown.
- p = null;
-
-
-
-}
-
-//--------------------------------------------------------------------
-
-private static String getLine(BufferedReader toprint)
-{
- try {
- return toprint.readLine();
- } catch (IOException e) {
- // If we get here, this means that the forked process has
- // been killed by the shutdown thread. We just exit without
- // printing this exception.
- System.exit(1);
- return null; // Never reached, but needed.
- }
-}
-
-
-// --------------------------------------------------------------------
-
-private static void usage()
-{
- System.err.println("Usage:");
- System.err.println(" peersim.RangeSimulator <configfile> [property]*");
-}
-
-//--------------------------------------------------------------------
-
-RangeSimulator()
-{
-}
-
-/**
- * Stop the process executing the external java virtual machine.
- */
-public void doStop()
-{
- if (p != null)
- p.destroy();
-}
-
-/**
- * Wait until the java virtual machine has terminated; it won't be
- * used in this class, but you never know.
- */
-public void join() throws InterruptedException
-{
- p.waitFor();
-}
-
-}
+++ /dev/null
-/*
- * 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.rangesim;
-
-import java.io.*;
-import java.util.*;
-
-import peersim.config.*;
-import peersim.core.*;
-
-/**
- * This OutputStream uses an underlying stream to output
- * data. Each line (terminated with `\n`) is augmented
- * with a tag character. This is used to discriminate
- * among standard error and standard output. This
- * feature is needed for launching new JVMs; it should
- * not be used for other purposes.
- *
- * @author Alberto Montresor
- * @version $Revision: 1.5 $
- */
-public class TaggedOutputStream extends PrintStream
-{
-
-//--------------------------------------------------------------------------
-//Constants
-//--------------------------------------------------------------------------
-
-/**
- * This character is appended at the end of each line.
- */
-public static final int TAG = 1;
-
-//--------------------------------------------------------------------------
-//Parameters
-//--------------------------------------------------------------------------
-
-/**
- * This parameter contains the string that should be printed on each
- * line, containing the values of the range parameters for the experiment
- * which is being run. The full name of this configuration string is
- * prefixed by {@value peersim.Simulator#PAR_REDIRECT}.
- * @config
- */
-public static final String PAR_RANGES = "ranges";
-
-/**
- * This parameter contains the list of observers for which the string
- * contained in parameter {@value #PAR_RANGES} should be augmented with
- * a "TIME <t>" specification regarding current time. Observers are
- * separated by one of this characters: ' ' - ',' - ';'.
- * @config
- */
-public static final String PAR_TIME = "simulation.timed-observers";
-
-
-//--------------------------------------------------------------------------
-//Fields
-//--------------------------------------------------------------------------
-
-/** Variable used to save the original System.out to simplify printing */
-private PrintStream stdout;
-
-/** Buffer used to store a single line; it can grow */
-private byte[] buffer = new byte[1024];
-
-/** Current size of the buffer */
-private int size;
-
-/** The value of the PAR_RANGES parameter */
-private final String ranges;
-
-/** The value of the PAR_TIME parameter */
-private final ArrayList<String> obstime;
-
-//--------------------------------------------------------------------------
-//Initialization
-//--------------------------------------------------------------------------
-
-
-/**
- * Creates a tagged output stream that prints the tagged
- * output on the specified stream.
- */
-public TaggedOutputStream(String prefix)
-{
- super(System.out);
-
- obstime = new ArrayList<String>();
- String[] obs = Configuration.getString(PAR_TIME, "").split("[ :,]");
- for (int i=0; i < obs.length; i++) {
- obstime.add("control." + obs[i]);
- }
- ranges = Configuration.getString(prefix + "." + PAR_RANGES, "");
- stdout = System.out;
- size = 0;
-}
-
-//--------------------------------------------------------------------------
-//Methods
-//--------------------------------------------------------------------------
-
-// Comment inherited from interface
-@Override
-public synchronized void write(byte[] b, int off, int len)
-{
- if (size+len > buffer.length) {
- byte[] tmp = new byte[Math.max(buffer.length*2, size+len)];
- System.arraycopy(buffer, 0, tmp, 0, size);
- buffer = tmp;
- }
- int last = off+len;
- for (int i=off; i < last; i++) {
- if (b[i] == '\n') {
- buffer[size++] = TAG;
- buffer[size++] = b[i];
- printLine();
- } else {
- buffer[size++] = b[i];
- }
- }
-}
-
-// Comment inherited from interface
-@Override
-public synchronized void write(int b)
-{
- if (size == buffer.length) {
- byte[] tmp = new byte[buffer.length*2];
- System.arraycopy(buffer, 0, tmp, 0, size);
- buffer = tmp;
- }
- if (b == '\n') {
- buffer[size++] = TAG;
- buffer[size++] = (byte) b;
- printLine();
- } else {
- buffer[size++] = (byte) b;
- }
-}
-
-/**
- * Actually prints a line, inserting ranges and time
- * when needed.
- */
-private void printLine()
-{
- String line = new String(buffer, 0, size);
- String[] parts = line.split(":");
- if (parts.length == 2) {
- stdout.print(parts[0]);
- stdout.print(": ");
- stdout.print(ranges);
- if (obstime.contains(parts[0]))
- stdout.print(" TIME " + CommonState.getTime() + " ");
- stdout.print(parts[1]);
- } else {
- stdout.print(line);
- }
- size = 0;
-}
-
-}
+++ /dev/null
-/*
- * 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.reports;
-
-import peersim.config.*;
-import peersim.core.*;
-import peersim.util.*;
-
-/**
- * Control to observe the ball expansion, that is,
- * the number of nodes that are
- * accessible from a given node in at most 1, 2, etc steps.
- */
-public class BallExpansion extends GraphObserver
-{
-
-// ===================== fields =======================================
-// ====================================================================
-
-/**
- * This parameter defines the maximal distance we care about.
- * In other words, two nodes are further away, they will not be taken
- * into account when calculating statistics.
- * <p>
- * Defaults to the
- * network size (which means all distances are taken into account).
- * Note that this default is normally way too much; many low diameter graphs
- * have only short distances between the nodes. Setting a short
- * (but sufficient) distance saves memory.
- * Also note that the <em>initial</em> network
- * size is used if no value is given which might not be what you want if e.g. the
- * network is growing.
- * @config
- */
-private static final String PAR_MAXD = "maxd";
-
-/**
- * The number of nodes to print info about.
- * Defaults to 1000. If larger than the current network size, then the
- * current network size is used.
- * @config
- */
-private static final String PAR_N = "n";
-
-/**
- * If defined, statistics are printed instead over the minimal path lengths. Not
- * defined by default.
- * @config
- */
-private static final String PAR_STATS = "stats";
-
-private final int maxd;
-
-private final int n;
-
-private final boolean stats;
-
-/** working variable */
-private final int[] b;
-
-private final RandPermutation rp = new RandPermutation(CommonState.r);
-
-// ===================== initialization ================================
-// =====================================================================
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param name the configuration prefix for this class
- */
-public BallExpansion(String name)
-{
- super(name);
- maxd = Configuration.getInt(name + "." + PAR_MAXD, Network.size());
- n = Configuration.getInt(name + "." + PAR_N, 1000);
- stats = Configuration.contains(name + "." + PAR_STATS);
- b = new int[maxd];
-}
-
-// ====================== methods ======================================
-// =====================================================================
-
-/**
-* Prints information about ball expansion. It uses {@value #PAR_N} nodes to
-* collect statistics.
-* If parameter {@value #PAR_STATS} is defined then the output is
-* produced by {@link IncrementalStats#toString}, over the values of minimal
-* distances from the given number of nodes to all other nodes in the network.
-* If at least one node is unreachable from any selected starting node, then
-* the path length is taken as infinity and statistics are calculated
-* accordingly. In that case, {@link IncrementalStats#getMaxCount()} returns
-* the number of nodes of "infinite distance", that is, the number of
-* unreachable nodes.
-* Otherwise one line is printed for all nodes we observe, containing the
-* number of nodes at distance 1, 2, etc, separated by spaces.
-* In this output format, unreachable nodes are simply ignored, but of course
-* the sum of the numbers in one line can be used to detect partitioning if
-* necessary.
-* Finally, note that the {@value #PAR_N} nodes are not guaranteed to be the
-* same nodes over consecutive calls to this method.
-* @return always false
-*/
-public boolean execute() {
-
- updateGraph();
- System.out.print(name + ": ");
- rp.reset(g.size());
- if (stats)
- {
- IncrementalStats is = new IncrementalStats();
- for (int i = 0; i < n && i < g.size(); ++i)
- {
- ga.dist(g, rp.next());
- for (int j=0; j<g.size(); j++)
- {
- if (ga.d[j] > 0)
- is.add(ga.d[j]);
- else if (ga.d[j] == -1)
- is.add(Double.POSITIVE_INFINITY);
- // deliberately left ga.d[j]==0 out, as we don't
- // want to count trivial distance to oneself.
- }
- }
- System.out.println(is);
- }
- else
- {
- System.out.println();
- for (int i = 0; i < n && i < g.size(); ++i)
- {
- ga.flooding(g, b, rp.next());
- int j = 0;
- while (j < b.length && b[j] > 0)
- {
- System.out.print(b[j++] + " ");
- }
- System.out.println();
- }
- }
- return false;
-}
-
-}
+++ /dev/null
-/*
- * 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.reports;
-
-import peersim.config.Configuration;
-import peersim.graph.GraphAlgorithms;
-import peersim.util.IncrementalStats;
-
-/**
- * Control to observe the clustering coefficient.
- * @see GraphAlgorithms#clustering
- */
-public class Clustering extends GraphObserver
-{
-
-// ===================== fields =======================================
-// ====================================================================
-
-/**
- * The number of nodes to collect info about. Defaults to the size of the graph.
- * @config
- */
-private static final String PAR_N = "n";
-
-private final int n;
-
-// ===================== initialization ================================
-// =====================================================================
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param name the configuration prefix for this class
- */
-public Clustering(String name)
-{
- super(name);
- n = Configuration.getInt(name + "." + PAR_N, Integer.MAX_VALUE);
-}
-
-// ====================== methods ======================================
-// =====================================================================
-
-/**
-* Prints information about the clustering coefficient.
-* It uses {@value #PAR_N} nodes to collect statistics.
-* The output is
-* produced by {@link IncrementalStats#toString}, over the values of
-* the clustering coefficients of the given number of nodes.
-* Clustering coefficients are calculated by {@link GraphAlgorithms#clustering}.
-* @return always false
-*/
-public boolean execute()
-{
- IncrementalStats stats = new IncrementalStats();
- updateGraph();
- for (int i = 0; i < n && i < g.size(); ++i) {
- stats.add(GraphAlgorithms.clustering(g, i));
- }
- System.out.println(name + ": " + stats);
- return false;
-}
-
-}
+++ /dev/null
-/*
- * 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.reports;
-
-import java.util.Iterator;
-import java.util.Map;
-import peersim.config.Configuration;
-import peersim.util.IncrementalStats;
-
-/**
- * Reports statistics about connectivity properties of the network, such as
- * weakly or strongly connected clusters.
- */
-public class ConnectivityObserver extends GraphObserver
-{
-
-//--------------------------------------------------------------------------
-//Parameters
-//--------------------------------------------------------------------------
-
-/**
- * The parameter used to request cluster size statistics instead of the usual
- * list of clusters. Not set by default.
- * @config
- */
-private static final String PAR_STATS = "stats";
-
-/**
- * Defines the types of connected clusters to discover.
- * Possible values are
- * <ul>
- * <li>"wcc": weakly connected clusters</li>
- * <li>"scc": strongly connected clusters</li>
- * </ul>
- * Defaults to "wcc".
- * @config
- */
-private static final String PAR_TYPE = "type";
-
-//--------------------------------------------------------------------------
-//Fields
-//--------------------------------------------------------------------------
-
-/** {@link #PAR_STATS} */
-private final boolean sizestats;
-
-/** {@link #PAR_TYPE} */
-private final String type;
-
-//--------------------------------------------------------------------------
-//Initialization
-//--------------------------------------------------------------------------
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param name the configuration prefix for this class
- */
-public ConnectivityObserver(String name)
-{
- super(name);
- sizestats = Configuration.contains(name + "." + PAR_STATS);
- type = Configuration.getString(name + "." + PAR_TYPE,"wcc");
-}
-
-//--------------------------------------------------------------------------
-//Methods
-//--------------------------------------------------------------------------
-
-/**
-* Prints information about clusters.
-* If parameter {@value #PAR_STATS} is defined then the output is
-* produced by {@link IncrementalStats#toString}, over the sizes of the
-* clusters.
-* Otherwise one line is printed that contains the string representation of
-* a map, that holds cluster IDs mapped to cluster sizes.
-* The meaning of the cluster IDs is not specified, but is printed for
-* debugging purposes.
-* @return always false
-* @see peersim.graph.GraphAlgorithms#tarjan
-* @see peersim.graph.GraphAlgorithms#weaklyConnectedClusters
-*/
-public boolean execute()
-{
- Map clst;
- updateGraph();
-
- if(type.equals("wcc"))
- clst=ga.weaklyConnectedClusters(g);
- else if(type.equals("scc"))
- clst=ga.tarjan(g);
- else
- throw new RuntimeException(
- "Unsupported connted cluster type '"+type+"'");
-
- if (!sizestats) {
- System.out.println(name + ": " + clst);
- } else {
- IncrementalStats stats = new IncrementalStats();
- Iterator it = clst.values().iterator();
- while (it.hasNext()) {
- stats.add(((Integer) it.next()).intValue());
- }
- System.out.println(name + ": " + stats);
- }
- return false;
-}
-
-}
+++ /dev/null
-/*
- * 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.reports;
-
-import peersim.config.*;
-import peersim.core.*;
-import peersim.util.*;
-
-/**
- * Prints several statistics about the node degrees in the graph.
- */
-public class DegreeStats extends GraphObserver
-{
-
-//--------------------------------------------------------------------------
-//Parameter
-//--------------------------------------------------------------------------
-
-/**
- * The number of nodes to be used for sampling the degree.
- * Defaults to full size of the graph.
- * @config
- */
-private static final String PAR_N = "n";
-
-/**
- * If defined, then the given number of nodes will be traced. That is, it is
- * guaranteed that in each call the same nodes will be picked in the same order.
- * If a node being traced fails, its degree will be considered 0. Not defined by
- * default.
- * @config
- */
-private static final String PAR_TRACE = "trace";
-
-/**
- * Selects a method to use when printing results. Three methods are known:
- * "stats" will use {@link IncrementalStats#toString}. "freq" will
- * use {@link IncrementalFreq#print}. "list" will print the
- * degrees of the sample nodes one by one in one line, separated by spaces.
- * Default is "stats".
- * @config
- */
-private static final String PAR_METHOD = "method";
-
-/**
- * Selects the types of links to print information about. Three methods are
- * known: "live": links pointing to live nodes, "dead": links pointing to nodes
- * that are unavailable and "all": both dead and live links summed. "all" and
- * "dead" require parameter {@value peersim.reports.GraphObserver#PAR_UNDIR}
- * to be unset (graph must be directed). Default is "live".
- * @config
- */
-private static final String PAR_TYPE = "linktype";
-
-//--------------------------------------------------------------------------
-//Parameter
-//--------------------------------------------------------------------------
-
-private final int n;
-
-private final boolean trace;
-
-private Node[] traced = null;
-
-private final String method;
-
-private final String type;
-
-private final RandPermutation rp = new RandPermutation(CommonState.r);
-
-private int nextnode = 0;
-
-//--------------------------------------------------------------------------
-//Initialization
-//--------------------------------------------------------------------------
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param name the configuration prefix for this class
- */
-public DegreeStats(String name)
-{
- super(name);
- n = Configuration.getInt(name + "." + PAR_N, -1);
- trace = Configuration.contains(name + "." + PAR_TRACE);
- method = Configuration.getString(name + "." + PAR_METHOD, "stats");
- type = Configuration.getString(name + "." + PAR_TYPE, "live");
- if ((type.equals("all") || type.equals("dead")) && undir) {
- throw new IllegalParameterException(
- name + "." + PAR_TYPE, " Parameter "+ name + "." +
- PAR_UNDIR + " must not be defined if " + name + "."
- + PAR_TYPE + "=" + type + ".");
- }
-}
-
-//--------------------------------------------------------------------------
-//Methods
-//--------------------------------------------------------------------------
-
-/**
- * Returns next node to get degree information about.
- */
-private int nextNodeId()
-{
- if (trace) {
- if (traced == null) {
- int nn = (n < 0 ? Network.size() : n);
- traced = new Node[nn];
- for (int j = 0; j < nn; ++j)
- traced[j] = Network.get(j);
- }
- return traced[nextnode++].getIndex();
- } else
- return rp.next();
-}
-
-// ---------------------------------------------------------------------
-
-/**
- * Returns degree information about next node.
- */
-private int nextDegree()
-{
- final int nodeid = nextNodeId();
- if (type.equals("live")) {
- return g.degree(nodeid);
- } else if (type.equals("all")) {
- return ((OverlayGraph) g).fullDegree(nodeid);
- } else if (type.equals("dead")) {
- return ((OverlayGraph) g).fullDegree(nodeid) - g.degree(nodeid);
- } else
- throw new RuntimeException(name + ": invalid type");
-}
-
-// ---------------------------------------------------------------------
-
-/**
- * Prints statistics about node degree. The format of the output is specified
- * by {@value #PAR_METHOD}. See also the rest of the configuration parameters.
- * @return always false
- */
-public boolean execute()
-{
- updateGraph();
- if (!trace)
- rp.reset(g.size());
- else
- nextnode = 0;
- final int nn = (n < 0 ? Network.size() : n);
- if (method.equals("stats")) {
- IncrementalStats stats = new IncrementalStats();
- for (int i = 0; i < nn; ++i)
- stats.add(nextDegree());
- System.out.println(name + ": " + stats);
- } else if (method.equals("freq")) {
- IncrementalFreq stats = new IncrementalFreq();
- for (int i = 0; i < nn; ++i)
- stats.add(nextDegree());
- stats.print(System.out);
- System.out.println("\n\n");
- } else if (method.equals("list")) {
- System.out.print(name + ": ");
- for (int i = 0; i < nn; ++i)
- System.out.print(nextDegree() + " ");
- System.out.println();
- }
- return false;
-}
-
-}
+++ /dev/null
-/*
- * 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.reports;
-
-import peersim.core.*;
-import peersim.config.Configuration;
-import peersim.graph.*;
-import peersim.cdsim.CDState;
-
-/**
-* Class that provides functionality for observing graphs.
-* It can efficiently create an undirected version of the graph, making sure
-* it is updated only when the simulation has advanced already, and provides
-* some common parameters.
-*/
-public abstract class GraphObserver implements Control {
-
-
-// ===================== fields =======================================
-// ====================================================================
-
-/**
- * The protocol to operate on.
- * @config
- */
-private static final String PAR_PROT = "protocol";
-
-/**
- * If defined, the undirected version of the graph will be analyzed. Not defined
- * by default.
- * @config
- */
-protected static final String PAR_UNDIR = "undir";
-
-/**
-* Alias for {@value #PAR_UNDIR}.
-* @config
-*/
-private static final String PAR_UNDIR_ALT = "undirected";
-
-/**
- * If defined, the undirected version of the graph will be stored using much
- * more memory but observers will be in general a few times faster. As a
- * consequence, it will not work with large graphs. Not defined by default. It
- * is a static property, that is, it affects all graph observers that are used
- * in a simulation. That is, it is not a parameter of any observer, the name
- * should be specified as a standalone property.
- * @config
- */
-private static final String PAR_FAST = "graphobserver.fast";
-
-/** The name of this observer in the configuration */
-protected final String name;
-
-protected final int pid;
-
-protected final boolean undir;
-
-protected final GraphAlgorithms ga = new GraphAlgorithms();
-
-protected Graph g;
-
-// ---------------------------------------------------------------------
-
-private static int lastpid = -1234;
-
-private static long time = -1234;
-
-private static int phase = -1234;
-
-private static int ctime = -1234;
-
-private static Graph dirg;
-
-private static Graph undirg;
-
-private static boolean fast;
-
-/** If any instance of some extending class defines undir we need to
-maintain an undir graph. Note that the graph is stored in a static
-field so it is common to all instances. */
-private static boolean needUndir=false;
-
-// ===================== initialization ================================
-// =====================================================================
-
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param name the configuration prefix for this class
- */
-protected GraphObserver(String name) {
-
- this.name = name;
- pid = Configuration.getPid(name+"."+PAR_PROT);
- undir = (Configuration.contains(name + "." + PAR_UNDIR) |
- Configuration.contains(name + "." + PAR_UNDIR_ALT));
- GraphObserver.fast = Configuration.contains(PAR_FAST);
- GraphObserver.needUndir = (GraphObserver.needUndir || undir);
-}
-
-
-// ====================== methods ======================================
-// =====================================================================
-
-/**
-* Sets {@link #g}.
-* It MUST be called by any implementation of {@link #execute()} before
-* doing anything else.
-* Attempts to initialize {@link #g} from a
-* pre-calculated graph stored in a static field, but first it
-* checks whether it needs to be updated.
-* If the simulation time has progressed or it was calculated for a different
-* protocol, then updates this static graph as well.
-* The purpose of this mechanism is to save the time of constructing the
-* graph if many observers are run on the same graph. Time savings can be very
-* significant if the undirected version of the same graph is observed by many
-* observers.
-*/
-protected void updateGraph() {
-
- if( CommonState.getTime() != GraphObserver.time ||
- (CDState.isCD() && (CDState.getCycleT() != GraphObserver.ctime)) ||
- CommonState.getPhase() != GraphObserver.phase ||
- pid != GraphObserver.lastpid )
- {
- // we need to update the graphs
-
- GraphObserver.lastpid = pid;
- GraphObserver.time = CommonState.getTime();
- if( CDState.isCD() ) GraphObserver.ctime = CDState.getCycleT();
- GraphObserver.phase = CommonState.getPhase();
-
- GraphObserver.dirg = new OverlayGraph(pid);
- if( GraphObserver.needUndir )
- {
- if( fast )
- GraphObserver.undirg =
- new FastUndirGraph(GraphObserver.dirg);
- else
- GraphObserver.undirg =
- new ConstUndirGraph(GraphObserver.dirg);
- }
- }
-
- if( undir ) g = GraphObserver.undirg;
- else g = GraphObserver.dirg;
-}
-
-}
-
-
-
+++ /dev/null
-/*
- * 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.reports;
-
-import peersim.config.Configuration;
-import peersim.graph.GraphIO;
-import peersim.util.FileNameGenerator;
-import java.io.PrintStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-
-/**
-* Prints the whole graph in a given format.
-*/
-public class GraphPrinter extends GraphObserver {
-
-
-// ===================== fields =======================================
-// ====================================================================
-
-/**
-* This is the prefix of the filename where the graph is saved.
-* The extension is ".graph" and after the prefix the basename contains
-* a numeric index that is incremented at each saving point.
-* If not given, the graph is dumped on the standard output.
-* @config
-*/
-private static final String PAR_BASENAME = "outf";
-
-/**
-* The name for the format of the output. Defaults to "neighborlist",
-* which is a plain dump of neighbors. The class
-* {@link peersim.dynamics.WireFromFile} can read this format.
-* Other supported formats are "chaco" to be used with Yehuda Koren's
-* Embedder, "netmeter" to be used with Sergi Valverde's netmeter and also
-* with pajek,
-* "edgelist" that dumps one (directed) node pair in each line for each edge,
-* "gml" that is a generic format of many graph tools, and "dot" that can
-* be used with the graphviz package.
-* @see GraphIO#writeEdgeList
-* @see GraphIO#writeChaco
-* @see GraphIO#writeNeighborList
-* @see GraphIO#writeNetmeter
-* @config
-*/
-private static final String PAR_FORMAT = "format";
-
-private final String baseName;
-
-private final FileNameGenerator fng;
-
-private final String format;
-
-
-// ===================== initialization ================================
-// =====================================================================
-
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param name the configuration prefix for this class
- */
-public GraphPrinter(String name) {
-
- super(name);
- baseName = Configuration.getString(name+"."+PAR_BASENAME,null);
- format = Configuration.getString(name+"."+PAR_FORMAT,"neighborlist");
- if(baseName!=null) fng = new FileNameGenerator(baseName,".graph");
- else fng = null;
-}
-
-
-// ====================== methods ======================================
-// =====================================================================
-
-
-/**
-* Saves the graph according to the specifications in the configuration.
-* @return always false
-*/
-public boolean execute() {
-try {
- updateGraph();
-
- System.out.print(name+": ");
-
- // initialize output streams
- FileOutputStream fos = null;
- PrintStream pstr = System.out;
- if( baseName != null )
- {
- String fname = fng.nextCounterName();
- fos = new FileOutputStream(fname);
- System.out.println("writing to file "+fname);
- pstr = new PrintStream(fos);
- }
- else System.out.println();
-
- if( format.equals("neighborlist") )
- GraphIO.writeNeighborList(g, pstr);
- else if( format.equals("edgelist") )
- GraphIO.writeEdgeList(g, pstr);
- else if( format.equals("chaco") )
- GraphIO.writeChaco(g, pstr);
- else if( format.equals("netmeter") )
- GraphIO.writeNetmeter(g, pstr);
- else if( format.equals("gml") )
- GraphIO.writeGML(g, pstr);
- else if( format.equals("dot") )
- GraphIO.writeDOT(g, pstr);
- else
- System.err.println(name+": unsupported format "+format);
-
- if( fos != null ) fos.close();
-
- return false;
-}
-catch( IOException e )
-{
- throw new RuntimeException(e);
-}
-}
-
-}
-
+++ /dev/null
-/*
- * 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.reports;
-
-import peersim.config.Configuration;
-import peersim.graph.GraphAlgorithms;
-import peersim.util.IncrementalStats;
-
-/**
-* Prints reports on the graph like average clustering and average path length,
-* based on random sampling of the nodes.
-* In fact its functionality is a subset of the union of {@link Clustering}
-* and {@link BallExpansion}, and therefore is redundant,
-* but it is there for historical reasons.
-* @see BallExpansion
-* @see Clustering
-*/
-public class GraphStats extends GraphObserver {
-
-
-// ===================== fields =======================================
-// ====================================================================
-
-/**
-* The number of nodes to use for
-* sampling average path length.
-* Statistics are printed over a set of node pairs.
-* To create the set of pairs, we select the given number of different nodes
-* first, and then pair all these nodes with every other node in the network.
-* If zero is given, then no statistics
-* will be printed about path length. If a negative value is given then
-* the value is the full size of the graph.
-* Defaults to zero.
-* @config
-*/
-private static final String PAR_NL = "nl";
-
-/**
-* The number of nodes to use to sample
-* average clustering.
-* If zero is given, then no statistics
-* will be printed about clustering. If a negative value is given then
-* the value is the full size of the graph.
-* Defaults to zero.
-* @config
-*/
-private static final String PAR_NC = "nc";
-
-private final int nc;
-
-private final int nl;
-
-
-// ===================== initialization ================================
-// =====================================================================
-
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param name the configuration prefix for this class
- */
-public GraphStats(String name) {
-
- super(name);
- nl = Configuration.getInt(name+"."+PAR_NL,0);
- nc = Configuration.getInt(name+"."+PAR_NC,0);
-}
-
-
-// ====================== methods ======================================
-// =====================================================================
-
-/**
-* Returns statistics over minimal path length and clustering.
-* The output is the average over the set of
-* clustering coefficients of randomly selected nodes, and the
-* set of distances from randomly selected nodes to all the other nodes.
-* The output is always concatenated in one line, containing zero, one or two
-* numbers (averages) as defined by the config parameters.
-* Note that the path length between a pair of nodes can be infinite, in which
-* case the statistics will reflect this (the average will be infinite, etc).
-* See also the configuration parameters.
-* @return always false
-* @see BallExpansion
-* @see Clustering
-*/
-public boolean execute() {
-
- System.out.print(name+": ");
-
- IncrementalStats stats = new IncrementalStats();
- updateGraph();
-
- if( nc != 0 )
- {
- stats.reset();
- final int n = ( nc<0 ? g.size() : nc );
- for(int i=0; i<n && i<g.size(); ++i)
- {
- stats.add(GraphAlgorithms.clustering(g,i));
- }
- System.out.print(stats.getAverage()+" ");
- }
-
- if( nl != 0 )
- {
- stats.reset();
- final int n = ( nl<0 ? g.size() : nl );
- outerloop:
- for(int i=0; i<n && i<g.size(); ++i)
- {
- ga.dist(g,i);
- for(int j=0; j<g.size(); ++j)
- {
- if( j==i ) continue;
- if (ga.d[j] == -1)
- {
- stats.add(Double.POSITIVE_INFINITY);
- break outerloop;
- }
- else
- stats.add(ga.d[j]);
- }
- }
- System.out.print(stats.getAverage());
- }
-
- System.out.println();
- return false;
-}
-
-}
-
+++ /dev/null
-/*
- * 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.reports;
-
-import peersim.core.*;
-
-/**
- * This observer reports memory utilization (max, total and
- * free, as defined by <code>java.lang.Runtime</code>).
- *
- * @author Alberto Montresor
- * @version $Revision: 1.1 $
- */
-public class MemoryObserver implements Control
-{
-
-/** The runtime object to obtain memory info */
-private final static Runtime r = Runtime.getRuntime();
-
-/** The prefix to be printed */
-private final String prefix;
-
-/**
- * Constructor to be instantiated in PeerSim.
- * @param prefix
- */
-public MemoryObserver(String prefix)
-{
- this.prefix = prefix;
-}
-
-public boolean execute()
-{
- System.out.println(prefix + ": max=" + r.maxMemory() + ", total=" +
- r.totalMemory() + ", free=" + r.freeMemory());
- return false;
-}
-
-}
+++ /dev/null
-/*
- * 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.reports;
-
-import peersim.core.*;
-import peersim.config.Configuration;
-import peersim.graph.*;
-import peersim.util.IncrementalStats;
-import java.util.Map;
-import java.util.Iterator;
-
-/**
- * It tests the network for robustness to random node removal.
- * It does not actually remove
- * nodes, it is only an observer, so can be applied several times during the
- * simulation. A warning though: as a side effect it <em>may
- * shuffle the network</em> (see {@value #PAR_N}) so if this is an issue,
- * it should not be used,
- * or only after the simulation has finished.
- */
-public class RandRemoval extends GraphObserver
-{
-
-// ===================== fields =======================================
-// ====================================================================
-
-// XXX remove side effect
-/**
- * This parameter defines the number of runs of the iterative removal procedure
- * to get statistics. Look out: if set to a value larger than 1 then as a side
- * effect <em>the overlay will be shuffled</em>. Defaults to 1.
- * @config
- */
-private static final String PAR_N = "n";
-
-private final int n;
-
-// ===================== initialization ================================
-// =====================================================================
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param name the configuration prefix for this class
- */
-public RandRemoval(String name)
-{
- super(name);
- n = Configuration.getInt(name + "." + PAR_N, 1);
-}
-
-// ====================== methods ======================================
-// =====================================================================
-
-/**
-* Prints results of node removal tests. The following experiment is
-* repeated {@value #PAR_N} times. From the graph 50%, 51%, ..., 99% of the nodes
-* are removed at random. For all percentages it is calculated what is
-* the maximal
-* clustersize (weakly connected clusters) and the number of
-* clusters in the remaining graph.
-* These values are averaged over the experiments, and for all 50 different
-* percentage values a line is printed that contains the respective averages,
-* first the average maximal cluster size, followed by the average number
-* of clusters.
-* @return always false
-*/
-public boolean execute()
-{
- if( n < 1 ) return false;
- updateGraph();
-
- System.out.println(name + ":");
-
- final int size = Network.size();
- final int steps = 50;
- IncrementalStats[] maxClust = new IncrementalStats[steps];
- IncrementalStats[] clustNum = new IncrementalStats[steps];
- for (int i = 0; i < steps; ++i) {
- maxClust[i] = new IncrementalStats();
- clustNum[i] = new IncrementalStats();
- }
- for (int j = 0; j < n; ++j) {
- PrefixSubGraph sg = new PrefixSubGraph(g);
- IncrementalStats stats = new IncrementalStats();
- for (int i = 0; i < steps; i++) {
- sg.setSize(size / 2 - i * (size / 100));
- Map clst = ga.weaklyConnectedClusters(sg);
- stats.reset();
- Iterator it = clst.values().iterator();
- while (it.hasNext()) {
- stats.add(((Integer) it.next()).intValue());
- }
- maxClust[i].add(stats.getMax());
- clustNum[i].add(clst.size());
- }
- if( j+1 < n ) Network.shuffle();
- }
- for (int i = 0; i < steps; ++i) {
- System.out.println(maxClust[i].getAverage() + " "
- + clustNum[i].getAverage());
- }
- return false;
-}
-
-}
+++ /dev/null
-/*
- * 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.transport;
-
-
-/**
- * This static singleton emulates an underlying router network
- * of fixed size, and stores the latency measurements for all pairs
- * of routers.
- *
- * @author Alberto Montresor
- * @version $Revision: 1.6 $
- */
-public class E2ENetwork
-{
-
-//---------------------------------------------------------------------
-//Fields
-//---------------------------------------------------------------------
-
-/**
- * True if latency between nodes is considered symmetric. False otherwise.
- */
-private static boolean symm;
-
-/**
- * Size of the router network.
- */
-private static int size;
-
-/**
- * Latency distances between nodes.
- */
-private static int[][] array;
-
-//---------------------------------------------------------------------
-//Initialization
-//---------------------------------------------------------------------
-
-/** Disable instance construction */
-private E2ENetwork() {}
-
-//---------------------------------------------------------------------
-//Methods
-//---------------------------------------------------------------------
-
-/**
- * Resets the network, by creating a triangular (if symm is true) or
- * a rectangular (if symm is false) array of integers. Initially all
- * latencies between any pairs are set to be 0.
- * @param size the number or routers
- * @param symm if latency is symmetric between all pairs of routers
- */
-public static void reset(int size, boolean symm)
-{
- E2ENetwork.symm = symm;
- E2ENetwork.size = size;
- array = new int[size][];
- for (int i=0; i < size; i++) {
- if (symm)
- array[i] = new int[i];
- else
- array[i] = new int[size];
- }
-}
-
-//---------------------------------------------------------------------
-
-/**
- * Returns the latency associated to the specified (sender, receiver)
- * pair. Routers are indexed from 0.
- *
- * @param sender the index of the sender
- * @param receiver the index of the receiver
- * @return the latency associated to the specified (sender, receiver)
- * pair.
- */
-public static int getLatency(int sender, int receiver)
-{
- if (sender == receiver)
- return 0;
- // XXX There should be the possibility to fix the delay.
- if (symm) {
- // Symmetric network
- if (sender < receiver) {
- int tmp = sender;
- sender = receiver;
- receiver = tmp;
- }
- }
- return array[sender][receiver];
-}
-
-//---------------------------------------------------------------------
-
-/**
- * Sets the latency associated to the specified (sender, receiver)
- * pair. Routers are indexed from 0.
- *
- * @param sender the index of the sender
- * @param receiver the index of the receiver
- * @param latency the latency to be set
- */
-public static void setLatency(int sender, int receiver, int latency)
-{
- if (symm) {
- // Symmetric network
- if (sender < receiver) {
- int tmp = sender;
- sender = receiver;
- receiver = tmp;
- }
- }
- array[sender][receiver] = latency;
-}
-
-//---------------------------------------------------------------------
-
-/**
- * Returns the current size of the underlying network (i.e., the number of
- * routers).
- */
-public static int getSize()
-{
- return size;
-}
-
-}
+++ /dev/null
-/*
- * 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.transport;
-
-import peersim.config.*;
-import peersim.core.*;
-import peersim.edsim.*;
-
-
-/**
- * This transport protocol is based on the {@link E2ENetwork} class.
- * Each instance
- * of this transport class is assigned to one of the routers contained in
- * the (fully static singleton) {@link E2ENetwork},
- * and subsequently the {@link E2ENetwork} class is used to obtain the
- * latency for messages sending based on the router assignment.
- *
- * @author Alberto Montresor
- * @version $Revision: 1.11 $
- */
-public class E2ETransport implements Transport, RouterInfo
-{
-
-//---------------------------------------------------------------------
-//Parameters
-//---------------------------------------------------------------------
-
-/**
- * The delay that corresponds to the time spent on the source (and destination)
- * nodes. In other words, full latency is calculated by fetching the latency
- * that belongs to communicating between two routers, incremented by
- * twice this delay. Defaults to 0.
- * @config
- */
-private static final String PAR_LOCAL = "local";
-
-//---------------------------------------------------------------------
-//Static fields
-//---------------------------------------------------------------------
-
-/** Identifier of this transport protocol */
-private static int tid;
-
-/** Local component of latency */
-private static long local;
-
-//---------------------------------------------------------------------
-//Fields
-//---------------------------------------------------------------------
-
-/** Identifier of the internal node */
-private int router = -1;
-
-//---------------------------------------------------------------------
-//Initialization
-//---------------------------------------------------------------------
-
-/**
- * Reads configuration parameters.
- */
-public E2ETransport(String prefix)
-{
- tid = CommonState.getPid();
- local = Configuration.getLong(prefix + "." + PAR_LOCAL, 0);
-}
-
-//---------------------------------------------------------------------
-
-/**
- * Clones the object.
- */
-public Object clone()
-{
- E2ETransport e2e=null;
- try { e2e=(E2ETransport)super.clone(); }
- catch( CloneNotSupportedException e ) {} // never happens
- return e2e;
-}
-
-//---------------------------------------------------------------------
-//Methods inherited by Transport
-//---------------------------------------------------------------------
-
-/**
-* Delivers the message reliably, with the latency calculated by
-* {@link #getLatency}.
-*/
-public void send(Node src, Node dest, Object msg, int pid)
-{
- /* Assuming that the sender corresponds to the source node */
- E2ETransport sender = (E2ETransport) src.getProtocol(tid);
- E2ETransport receiver = (E2ETransport) dest.getProtocol(tid);
- long latency =
- E2ENetwork.getLatency(sender.router, receiver.router) + local*2;
- EDSimulator.add(latency, msg, dest, pid);
-}
-
-//---------------------------------------------------------------------
-
-/**
-* Calculates latency using the static singleton {@link E2ENetwork}.
-* It looks up which routers the given nodes are assigned to, then
-* looks up the corresponding latency. Finally it increments this value
-* by adding twice the local delay configured by {@value #PAR_LOCAL}.
-*/
-public long getLatency(Node src, Node dest)
-{
- /* Assuming that the sender corresponds to the source node */
- E2ETransport sender = (E2ETransport) src.getProtocol(tid);
- E2ETransport receiver = (E2ETransport) dest.getProtocol(tid);
- return E2ENetwork.getLatency(sender.router, receiver.router) + local*2;
-}
-
-
-//---------------------------------------------------------------------
-//Methods inherited by RouterInfo
-//---------------------------------------------------------------------
-
-/**
- * Associates the node hosting this transport protocol instance with
- * a router in the router network.
- *
- * @param router the numeric index of the router
- */
-public void setRouter(int router)
-{
- this.router = router;
-}
-
-//---------------------------------------------------------------------
-
-/**
- * @return the router associated to this transport protocol.
- */
-public int getRouter()
-{
- return router;
-}
-
-}
+++ /dev/null
-/*
- * 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.transport;
-
-import java.io.*;
-import java.util.*;
-import peersim.config.*;
-import peersim.core.Control;
-
-/**
- * Initializes static singleton {@link E2ENetwork} by reading a king data set.
- *
- * @author Alberto Montresor
- * @version $Revision: 1.9 $
- */
-public class KingParser implements Control
-{
-
-// ---------------------------------------------------------------------
-// Parameters
-// ---------------------------------------------------------------------
-
-/**
- * The file containing the King measurements.
- * @config
- */
-private static final String PAR_FILE = "file";
-
-/**
- * The ratio between the time units used in the configuration file and the
- * time units used in the Peersim simulator.
- * @config
- */
-private static final String PAR_RATIO = "ratio";
-
-// ---------------------------------------------------------------------
-// Fields
-// ---------------------------------------------------------------------
-
-/** Name of the file containing the King measurements. */
-private String filename;
-
-/**
- * Ratio between the time units used in the configuration file and the time
- * units used in the Peersim simulator.
- */
-private double ratio;
-
-/** Prefix for reading parameters */
-private String prefix;
-
-// ---------------------------------------------------------------------
-// Initialization
-// ---------------------------------------------------------------------
-
-/**
- * Read the configuration parameters.
- */
-public KingParser(String prefix)
-{
- this.prefix = prefix;
- ratio = Configuration.getDouble(prefix + "." + PAR_RATIO, 1);
- filename = Configuration.getString(prefix + "." + PAR_FILE, null);
-}
-
-// ---------------------------------------------------------------------
-// Methods
-// ---------------------------------------------------------------------
-
-/**
- * Initializes static singleton {@link E2ENetwork} by reading a king data set.
-* @return always false
-*/
-public boolean execute()
-{
- BufferedReader in = null;
- if (filename != null) {
- try {
- in = new BufferedReader(new FileReader(filename));
- } catch (FileNotFoundException e) {
- throw new IllegalParameterException(prefix + "." + PAR_FILE, filename
- + " does not exist");
- }
- } else {
- in = new BufferedReader( new InputStreamReader(
- ClassLoader.getSystemResourceAsStream("t-king.map")
- ) );
- }
-
- // XXX If the file format is not correct, we will get quite obscure
- // exceptions. To be improved.
-
- String line = null;
- // Skip initial lines
- int size = 0;
- int lc = 1;
- try {
- while ((line = in.readLine()) != null && !line.startsWith("node")) lc++;
- while (line != null && line.startsWith("node")) {
- size++;
- lc++;
- line = in.readLine();
- }
- } catch (IOException e) {
- System.err.println("KingParser: " + filename + ", line " + lc + ":");
- e.printStackTrace();
- try { in.close(); } catch (IOException e1) { };
- System.exit(1);
- }
- E2ENetwork.reset(size, true);
- if (line == null) {
- System.err.println("KingParser: " + filename + ", line " + lc + ":");
- System.err.println("No latency matrix contained in the specified file");
- try { in.close(); } catch (IOException e1) { };
- System.exit(1);
- }
-
- System.err.println("KingParser: read " + size + " entries");
-
- try {
- do {
- StringTokenizer tok = new StringTokenizer(line, ", ");
- if (tok.countTokens() != 3) {
- System.err.println("KingParser: " + filename + ", line " + lc + ":");
- System.err.println("Specified line does not contain a <node1, node2, latency> triple");
- try { in.close(); } catch (IOException e1) { };
- System.exit(1);
- }
- int n1 = Integer.parseInt(tok.nextToken()) - 1;
- int n2 = Integer.parseInt(tok.nextToken()) - 1;
- int latency = (int) (Double.parseDouble(tok.nextToken()) * ratio);
- E2ENetwork.setLatency(n1, n2, latency);
- lc++;
- line = in.readLine();
- } while (line != null);
-
- in.close();
-
- } catch (IOException e) {
- System.err.println("KingParser: " + filename + ", line " + lc + ":");
- e.printStackTrace();
- try { in.close(); } catch (IOException e1) { };
- System.exit(1);
- }
-
-
- return false;
-}
-
-}
+++ /dev/null
-/*
- * 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.transport;
-
-/**
- * Generic interface to be implemented by protocols that need to be assigned to
- * routers. The idea is that each node is assigned to a router, by
- * invoking {@link #setRouter(int)} method. Routers are identified by
- * integer indexes (starting from 0), based on the assumption that the
- * router network
- * is static. The router information is then used by different
- * implementations to compute latency, congestion, etc.
- *
- * @author Alberto Montresor
- * @version $Revision: 1.4 $
- */
-public interface RouterInfo
-{
-
-/**
- * Associates the node hosting this transport protocol instance with
- * a router in the router network.
- *
- * @param router the numeric index of the router
- */
-public void setRouter(int router);
-
-/**
- * @return the router associated to this transport protocol.
- */
-public int getRouter();
-
-}
+++ /dev/null
-/*
- * 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.transport;
-
-import peersim.core.*;
-
-
-/**
- * This interface represents a generic transport protocol, used to
- * send messages through the underlying network. Generally, transport
- * protocols use {@link peersim.edsim.EDSimulator} to schedule the delivery of
- * messages with some appropriate delay. They can also model message omission
- * failure as well.
- *
- * @author Alberto Montresor
- * @version $Revision: 1.7 $
- */
-public interface Transport extends Protocol
-{
-
-/**
- * Sends message <code>msg</code> from node <code>src</code> to protocol
- * <code>pid</code> of node <code>dst</code>.
- *
- * @param src sender node
- * @param dest destination node
- * @param msg message to be sent
- * @param pid protocol identifier
- */
-public void send(Node src, Node dest, Object msg, int pid);
-
-
-/**
- * Return a latency estimate from node <code>src</code> to protocol
- * <code>pid</code> of node <code>dst</code>.
- *
- * @param src sender node
- * @param dest destination node
- */
-public long getLatency(Node src, Node dest);
-
-
-}
+++ /dev/null
-/*
- * 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.transport;
-
-import java.io.*;
-
-import peersim.config.*;
-import peersim.core.*;
-
-/**
- * Initializes static singleton {@link E2ENetwork} by reading a trace
- * file containing the latency distance measured between a set of
- * "virtual" routers. Latency is assumed to be symmetric, so the
- * latency between x and y is equal to the latency to y and x.
- *
- * The format of the file is as follows: all values are stored as
- * integers. The first value is the number of nodes considered.
- * The rest of the values correspond to a "strictly upper triangular
- * matrix" (see this
- * <a href="http://en.wikipedia.org/w/index.php?title=Triangular_matrix&oldid=82411128">
- * link</a>), ordered first by row than by column.
- *
- * @author Alberto Montresor
- * @version $Revision: 1.4 $
- */
-public class TriangularMatrixParser implements Control
-{
-
-// ---------------------------------------------------------------------
-// Parameters
-// ---------------------------------------------------------------------
-
-/**
- * This configuration parameter identifies the filename of the file
- * containing the measurements. First, the file is used as a pathname
- * in the local file system. If no file can be identified in this way,
- * the file is searched in the local classpath. If the file cannot be
- * identified again, an error message is reported.
- * @config
- */
-private static final String PAR_FILE = "file";
-
-/**
- * The ratio between the time units used in the configuration file and the
- * time units used in the Peersim simulator.
- * @config
- */
-private static final String PAR_RATIO = "ratio";
-
-// ---------------------------------------------------------------------
-// Fields
-// ---------------------------------------------------------------------
-
-/** Name of the file containing the measurements. */
-private String filename;
-
-/** Ratio read from PAR_RATIO */
-private double ratio;
-
-// ---------------------------------------------------------------------
-// Initialization
-// ---------------------------------------------------------------------
-
-/**
- * Read the configuration parameters.
- */
-public TriangularMatrixParser(String prefix)
-{
- filename = Configuration.getString(prefix + "." + PAR_FILE);
- ratio = Configuration.getDouble(prefix + "." + PAR_RATIO);
-}
-
-// ---------------------------------------------------------------------
-// Methods
-// ---------------------------------------------------------------------
-
-/**
- * Initializes static singleton {@link E2ENetwork} by reading a king data set.
-* @return always false
-*/
-public boolean execute()
-{
- try {
- ObjectInputStream in = null;
- try {
- in = new ObjectInputStream(
- new BufferedInputStream(
- new FileInputStream(filename)));
- System.err.println("TriangularMatrixParser: Reading " + filename + " from local file system");
- } catch (FileNotFoundException e) {
- in = new ObjectInputStream(
- new BufferedInputStream(
- ClassLoader.getSystemResourceAsStream(filename)));
- System.err.println("TriangularMatrixParser: Reading " + filename + " through the class loader");
- }
-
- // Read the number of nodes in the file (first four bytes).
- int size = in.readInt();
-
- // Reset the E2E network
- E2ENetwork.reset(size, true);
- System.err.println("TriangularMatrixParser: reading " + size + " rows");
-
- // If the file format is not correct, data will be read
- // incorrectly. Probably a good way to spot this is the
- // presence of negative delays, or an end of file.
-
- // Reading data
- int count = 0;
- for (int r=0; r < size; r++) {
- for (int c = r+1; c < size; c++) {
- int x = (int) (ratio*in.readInt());
- count++;
- E2ENetwork.setLatency(r,c,x);
- }
- }
- System.err.println("TriangularMatrixParser: Read " + count + " entries");
- } catch (IOException e) {
- throw new RuntimeException(e.getMessage());
- }
- return false;
-}
-
-}
+++ /dev/null
-/*
- * 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.transport;
-
-import peersim.config.*;
-import peersim.core.*;
-import peersim.edsim.*;
-
-
-/**
- * Implement a transport layer that reliably delivers messages with a random
- * delay, that is drawn from the configured interval according to the uniform
- * distribution.
- *
- * @author Alberto Montresor
- * @version $Revision: 1.14 $
- */
-public final class UniformRandomTransport implements Transport
-{
-
-//---------------------------------------------------------------------
-//Parameters
-//---------------------------------------------------------------------
-
-/**
- * String name of the parameter used to configure the minimum latency.
- * @config
- */
-private static final String PAR_MINDELAY = "mindelay";
-
-/**
- * String name of the parameter used to configure the maximum latency.
- * Defaults to {@value #PAR_MINDELAY}, which results in a constant delay.
- * @config
- */
-private static final String PAR_MAXDELAY = "maxdelay";
-
-//---------------------------------------------------------------------
-//Fields
-//---------------------------------------------------------------------
-
-/** Minimum delay for message sending */
-private final long min;
-
-/** Difference between the max and min delay plus one. That is, max delay is
-* min+range-1.
-*/
-private final long range;
-
-
-//---------------------------------------------------------------------
-//Initialization
-//---------------------------------------------------------------------
-
-/**
- * Reads configuration parameter.
- */
-public UniformRandomTransport(String prefix)
-{
- min = Configuration.getLong(prefix + "." + PAR_MINDELAY);
- long max = Configuration.getLong(prefix + "." + PAR_MAXDELAY,min);
- if (max < min)
- throw new IllegalParameterException(prefix+"."+PAR_MAXDELAY,
- "The maximum latency cannot be smaller than the minimum latency");
- range = max-min+1;
-}
-
-//---------------------------------------------------------------------
-
-/**
-* Returns <code>this</code>. This way only one instance exists in the system
-* that is linked from all the nodes. This is because this protocol has no
-* node specific state.
-*/
-public Object clone()
-{
- return this;
-}
-
-//---------------------------------------------------------------------
-//Methods
-//---------------------------------------------------------------------
-
-/**
- * Delivers the message with a random
- * delay, that is drawn from the configured interval according to the uniform
- * distribution.
-*/
-public void send(Node src, Node dest, Object msg, int pid)
-{
- // avoid calling nextLong if possible
- long delay = (range==1?min:min + CommonState.r.nextLong(range));
- EDSimulator.add(delay, msg, dest, pid);
-}
-
-/**
- * Returns a random
- * delay, that is drawn from the configured interval according to the uniform
- * distribution.
-*/
-public long getLatency(Node src, Node dest)
-{
- return (range==1?min:min + CommonState.r.nextLong(range));
-}
-
-
-}
+++ /dev/null
-/*
- * 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.transport;
-
-import peersim.config.*;
-import peersim.core.*;
-
-
-/**
- * Initializes {@link RouterInfo} protocols by assigning routers to them.
- * The number of routers is defined by static singleton {@link E2ENetwork}.
- *
- * @author Alberto Montresor
- * @version $Revision: 1.6 $
- */
-public class UniformRouterAssignment implements Control
-{
-
-//---------------------------------------------------------------------
-//Parameters
-//---------------------------------------------------------------------
-
-/**
- * Parameter name used to configure the {@link RouterInfo} protocol
- * that should be initialized.
- * @config
- */
-private static final String PAR_PROT = "protocol";
-
-//---------------------------------------------------------------------
-//Methods
-//---------------------------------------------------------------------
-
-/** Protocol identifier */
-private int pid;
-
-
-//---------------------------------------------------------------------
-//Initialization
-//---------------------------------------------------------------------
-
-/**
- * Reads configuration parameters.
- */
-public UniformRouterAssignment(String prefix)
-{
- pid = Configuration.getPid(prefix+"."+PAR_PROT);
-}
-
-//---------------------------------------------------------------------
-//Methods
-//---------------------------------------------------------------------
-
-/**
- * Initializes given {@link RouterInfo} protocol layer by assigning
- * routers randomly.
- * The number of routers is defined by static singleton {@link E2ENetwork}.
-* @return always false
-*/
-public boolean execute()
-{
- int nsize = Network.size();
- int nrouters = E2ENetwork.getSize();
- for (int i=0; i < nsize; i++) {
- Node node = Network.get(i);
- RouterInfo t = (RouterInfo) node.getProtocol(pid);
- int r = CommonState.r.nextInt(nrouters);
- t.setRouter(r);
- }
-
- return false;
-}
-
-}
-
+++ /dev/null
-/*
- * 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.transport;
-
-import peersim.config.*;
-import peersim.core.*;
-
-
-/**
- * This transport protocol can be combined with other transports
- * to simulate message losses. Its behavior is the following: each message
- * can be dropped based on the configured probability, or it will be sent
- * using the underlying transport protocol.
- * <p>
- * The memory requirements are minimal, as a single instance is created and
- * inserted in the protocol array of all nodes (because instances have no state
- * that depends on the hosting node).
- *
- * @author Alberto Montresor
- * @version $Revision: 1.13 $
- */
-public final class UnreliableTransport implements Transport
-{
-
-//---------------------------------------------------------------------
-//Parameters
-//---------------------------------------------------------------------
-
-/**
- * The name of the underlying transport protocol. This transport is
- * extended with dropping messages.
- * @config
- */
-private static final String PAR_TRANSPORT = "transport";
-
-/**
- * String name of the parameter used to configure the probability that a
- * message sent through this transport is lost.
- * @config
- */
-private static final String PAR_DROP = "drop";
-
-
-//---------------------------------------------------------------------
-//Fields
-//---------------------------------------------------------------------
-
-/** Protocol identifier for the support transport protocol */
-private final int transport;
-
-/** Probability of dropping messages */
-private final float loss;
-
-//---------------------------------------------------------------------
-//Initialization
-//---------------------------------------------------------------------
-
-/**
- * Reads configuration parameter.
- */
-public UnreliableTransport(String prefix)
-{
- transport = Configuration.getPid(prefix+"."+PAR_TRANSPORT);
- loss = (float) Configuration.getDouble(prefix+"."+PAR_DROP);
-}
-
-//---------------------------------------------------------------------
-
-/**
-* Returns <code>this</code>. This way only one instance exists in the system
-* that is linked from all the nodes. This is because this protocol has no
-* state that depends on the hosting node.
- */
-public Object clone()
-{
- return this;
-}
-
-//---------------------------------------------------------------------
-//Methods
-//---------------------------------------------------------------------
-
-/** Sends the message according to the underlying transport protocol.
-* With the configured probability, the message is not sent (i.e. the method does
-* nothing).
-*/
-public void send(Node src, Node dest, Object msg, int pid)
-{
- try
- {
- if (CommonState.r.nextFloat() >= loss)
- {
- // Message is not lost
- Transport t = (Transport) src.getProtocol(transport);
- t.send(src, dest, msg, pid);
- }
- }
- catch(ClassCastException e)
- {
- throw new IllegalArgumentException("Protocol " +
- Configuration.lookupPid(transport) +
- " does not implement Transport");
- }
-}
-
-/** Returns the latency of the underlying protocol.*/
-public long getLatency(Node src, Node dest)
-{
- Transport t = (Transport) src.getProtocol(transport);
- return t.getLatency(src, dest);
-}
-
-}
+++ /dev/null
-/*
- * 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.util;
-
-import java.util.Random;
-import java.lang.Math;
-
-/**
- * Extends the functionality of <code>java.util.Random</code>.
- */
-public class ExtendedRandom extends Random {
-
-private long lastSeed;
-
-// -------------------------------------------------------------------------
-
-/** Calls super constructor. Also stores the seed to be returned by
-{@link #getLastSeed}. */
-public ExtendedRandom(long seed) {
-
- super(seed);
- lastSeed = seed;
-}
-
-// -------------------------------------------------------------------------
-
-/**
- * Extracts the next integer, according to a Poisson distribution.
- *
- * @param mean The mean of the Poisson distribution.
- * @return An integer Poisson extraction.
- */
-public int nextPoisson(double mean) {
-
- double emean = Math.exp(-1 * mean);
- double product = 1;
- int count = 0;
- int result = 0;
- while (product >= emean) {
- product *= nextDouble();
- result = count;
- count++; // keep result one behind
- }
- return result;
-}
-
-// -------------------------------------------------------------------------
-
-/**
-* Implements nextLong(long) the same way nexInt(int) is implemented in
-* java.util.Random.
-* @param n the bound on the random number to be returned. Must be positive.
-* @return a pseudorandom, uniformly distributed long value between 0
-* (inclusive) and n (exclusive).
-*/
-public long nextLong(long n) {
-
- if (n<=0)
- throw new IllegalArgumentException("n must be positive");
-
- if ((n & -n) == n) // i.e., n is a power of 2
- {
- return nextLong()&(n-1);
- }
-
- long bits, val;
- do
- {
- bits = (nextLong()>>>1);
- val = bits % n;
- }
- while(bits - val + (n-1) < 0);
-
- return val;
-}
-
-// -------------------------------------------------------------------------
-
-/** Sets random seed. Calls super method but also stores the seed to be
-returned by {@link #getLastSeed}. */
-public void setSeed( long seed ) {
-
- super.setSeed(seed);
- lastSeed = seed;
-}
-
-// -------------------------------------------------------------------------
-
-/**
-* Returns the last random seed that was set explicitly. Either at
-* construction time or through {@link #setSeed}.
-*/
-public long getLastSeed() { return lastSeed; }
-
-// -------------------------------------------------------------------------
-
-/*
-public static void main(String[] args) {
-
- ExtendedRandom er = new ExtendedRandom(12345678);
- for(int i=0; i<100; ++i)
- System.out.println(er.nextLong(Long.parseLong(args[0])));
-
-}
-*/
-}
-
+++ /dev/null
-/*
- * 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.util;
-
-import java.io.*;
-
-
-/**
-* Generates a series of filenames for classes that have to save e.g.
-* snapshots regularly.
-*/
-public class FileNameGenerator {
-
-
-/**
-* The number of filenames already returned.
-*/
-private long counter = 0;
-
-/** The prefix of the filename */
-public final String prefix;
-
-/** The extension of the filename */
-public final String ext;
-
-
-// ==================== initialization ==============================
-// ==================================================================
-
-
-/**
-* @param prefix all returned names will be prefixed by this
-* @param ext will be appended to all returned names
-*/
-public FileNameGenerator(String prefix, String ext) {
-
- this.prefix=prefix;
- this.ext=ext;
-}
-
-
-// ===================== methods ====================================
-// ==================================================================
-
-
-/**
-* Generates a name based on a counter.
-* The format of the name returned is {@link #prefix} followed by
-* an 8 digit zero padded number, followed by {@link #ext}.
-* The first number used is zero.
-* @return the next filename after increasing the counter
-*/
-public String nextCounterName() {
-
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- (new PrintStream(baos)).printf("%08d",counter);
- counter++;
- return prefix+baos.toString()+ext;
-}
-
-// ------------------------------------------------------------------
-
-/*
-public static void main(String args[]) {
-
- FileNameGenerator fng = new FileNameGenerator(args[0],args[1]);
- for(int i=0; i<100; ++i) System.err.println(fng.nextCounterName());
-}
-*/
-}
-
+++ /dev/null
-/*
- * 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.util;
-
-import java.io.PrintStream;
-
-//XXX This implementation is very restricted, to be made more flexible
-// using hashtables.
-/**
-* A class that can collect frequency information on integer input.
-* right now it can handle only unsigned input. It simply ignores negative
-* numbers.
-*/
-public class IncrementalFreq implements Cloneable {
-
-
-// ===================== fields ========================================
-// =====================================================================
-
-/** The number of items inserted. */
-private int n;
-
-/** freq[i] holds the frequency of i. primitive implementation, to be changed */
-private int[] freq = null;
-
-/**
-* The capacity, if larger than 0. Added values larger than or equal to
-* this one will be ignored.
-*/
-private final int N;
-
-
-// ====================== initialization ==============================
-// ====================================================================
-
-
-/**
-* @param maxvalue Values in the input set larger than this one will be ignored.
-* However, if it is negative, no values are ignored.
-*/
-public IncrementalFreq(int maxvalue) {
-
- N = maxvalue+1;
- reset();
-}
-
-// --------------------------------------------------------------------
-
-/** Calls <code>this(-1)</code>, that is, no values will be ignored.
-* @see #IncrementalFreq(int) */
-public IncrementalFreq() {
-
- this(-1);
-}
-
-// --------------------------------------------------------------------
-
-/** Reset the state of the object. After calling this, all public methods
-* behave the same as they did after constructing the object.
-*/
-public void reset() {
-
- if( freq==null || N==0 ) freq = new int[0];
- else for(int i=0; i<freq.length; ++i) freq[i]=0;
- n = 0;
-}
-
-
-// ======================== methods ===================================
-// ====================================================================
-
-/**
- * Adds item <code>i</code> to the input set.
- * It calls <code>add(i,1)</code>.
- * @see #add(int,int)
- */
-public final void add( int i ) { add(i,1); }
-
-
-// --------------------------------------------------------------------
-
-/**
- * Adds item <code>i</code> to the input set <code>k</code> times.
- * That is, it increments counter <code>i</code> by <code>k</code>.
- * If, however, <code>i</code> is negative, or larger than the maximum defined
- * at construction time (if a maximum was set at all) the operation is ignored.
- */
-public void add( int i, int k ) {
-
- if( N>0 && i>=N ) return;
- if( i<0 || k<=0 ) return;
-
- // Increase number of items by k.
- n+=k;
-
- // If index i is out of bounds for the current array of counters,
- // increase the size of the array to i+1.
- if( i>=freq.length )
- {
- int tmp[] = new int[i+1];
- System.arraycopy(freq, 0, tmp, 0, freq.length);
- freq=tmp;
- }
-
- // Finally, increase counter i by k.
- freq[i]+=k;
-}
-
-// --------------------------------------------------------------------
-
-/** Returns number of processed data items.
-* This is the number of items over which the class holds statistics.
-*/
-public int getN() { return n; }
-
-// --------------------------------------------------------------------
-
-/** Returns the number of occurrences of the given integer. */
-public int getFreq(int i) {
-
- if( i>=0 && i<freq.length ) return freq[i];
- else return 0;
-}
-
-// --------------------------------------------------------------------
-
-
-/**
- * Performs an element-by-element vector subtraction of the
- * frequency vectors. If <code>strict</code> is true, it
- * throws an IllegalArgumentException if <code>this</code> is
- * not strictly larger than <code>other</code> (element by element)
- * (Note that both frequency vectors are positive.)
- * Otherwise just sets those elements in <code>this</code> to zero
- * that are smaller than those of <code>other</code>.
- * @param other The instance of IncrementalFreq to subtract
- * @param strict See above explanation
- */
-public void remove(IncrementalFreq other, boolean strict) {
-
- // check if other has non-zero elements in non-overlapping part
- if(strict && other.freq.length>freq.length)
- {
- for(int i=other.freq.length-1; i>=freq.length; --i)
- {
- if (other.freq[i]!=0)
- throw new IllegalArgumentException();
- }
- }
-
- final int minLength = Math.min(other.freq.length, freq.length);
- for (int i=minLength-1; i>=0; i--)
- {
- if (strict && freq[i] < other.freq[i])
- throw new IllegalArgumentException();
- final int remove = Math.min(other.freq[i], freq[i]);
- n -= remove;
- freq[i] -= remove;
- }
-}
-
-// ---------------------------------------------------------------------
-
-/**
-* Prints current frequency information. Prints a separate line for
-* all values from 0 to the capacity of the internal representation using the
-* format
-* <pre>
-* value occurrences
-* </pre>
-* That is, numbers with zero occurrences will also be printed.
-*/
-public void printAll( PrintStream out ) {
-
- for(int i=0; i<freq.length; ++i)
- {
- out.println(i+" "+freq[i]);
- }
-}
-
-// ---------------------------------------------------------------------
-
-/**
-* Prints current frequency information. Prints a separate line for
-* all values that have a number of occurrences different from zero using the
-* format
-* <pre>
-* value occurrences
-* </pre>
-*/
-public void print( PrintStream out ) {
-
- for(int i=0; i<freq.length; ++i)
- {
- if(freq[i]!=0) out.println(i+" "+freq[i]);
- }
-}
-
-// ---------------------------------------------------------------------
-
-public String toString() {
-
- StringBuilder result=new StringBuilder("");
- for(int i=0; i<freq.length; ++i)
- {
- if (freq[i] != 0)
- result.append(" (").append(i).append(","
- ).append(freq[i]).append(")");
- }
- return result.toString();
-}
-
-// ---------------------------------------------------------------------
-
-/** An alternative method to convert the object to String */
-public String toArithmeticExpression() {
-
- StringBuilder result=new StringBuilder("");
- for (int i=freq.length-1; i>=0; i--)
- {
- if (freq[i] != 0)
- result.append(freq[i]).append(
- "*").append(i).append("+");
- }
-
- if (result.length()==0)
- return "(empty)";
- else
- return result.substring(0, result.length()-1);
-}
-
-// ---------------------------------------------------------------------
-
-public Object clone() throws CloneNotSupportedException {
-
- IncrementalFreq result = (IncrementalFreq)super.clone();
- if( freq != null ) result.freq = freq.clone();
- return result;
-}
-
-// ---------------------------------------------------------------------
-
-/**
-* Tests equality between two IncrementalFreq instances.
-* Two objects are equal if both hold the same set of numbers that have
-* occurred non-zero times and the number of occurrences is also equal for
-* these numbers.
-*/
-public boolean equals(Object obj) {
-
- if( !( obj instanceof IncrementalFreq) ) return false;
- IncrementalFreq other = (IncrementalFreq)obj;
- final int minlength = Math.min(other.freq.length, freq.length);
-
- for (int i=minlength-1; i>=0; i--)
- if (freq[i] != other.freq[i])
- return false;
-
- if( freq.length > minlength ) other=this;
- for (int i=minlength; i<other.freq.length; i++)
- if( other.freq[i] != 0 )
- return false;
-
- return true;
-}
-
-// ---------------------------------------------------------------------
-
-/**
-* Hashcode (consistent with {@link #equals}). Probably you will never want to
-* use this, but since we have {@link #equals}, we must implement it.
-*/
-public int hashCode() {
-
- int sum = 0;
- for(int i=0; i<freq.length; ++i) sum += freq[i]*i;
- return sum;
-}
-
-// ---------------------------------------------------------------------
-
-/*
-public static void main(String[] pars) {
-
- IncrementalFreq ifq = new IncrementalFreq(Integer.parseInt(pars[0]));
- for(int i=1; i<pars.length; ++i)
- {
- ifq.add(Integer.parseInt(pars[i]));
- }
- ifq.print(System.out);
- System.out.println(ifq);
-}
-*/
-}
-
-
+++ /dev/null
-/*
- * 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.util;
-
-/**
-* A class that can keep track of some statistics like variance, average, min,
-* max incrementally. That is, when adding a new data item, it updates the
-* statistics.
-*/
-public class IncrementalStats {
-
-
-// ===================== fields ========================================
-// =====================================================================
-
-
-private double min;
-
-private double max;
-
-private double sum;
-
-private double sqrsum;
-
-private int n;
-
-private int countmin;
-
-private int countmax;
-
-// ====================== initialization ==============================
-// ====================================================================
-
-
-/** Calls {@link #reset}. */
-public IncrementalStats() { reset(); }
-
-// --------------------------------------------------------------------
-
-/** Resets the statistics to reflect the zero elements set.
-* Min and max are set to positive and negative infinity, respectively.
-*/
-public void reset() {
-
- countmin=0;
- countmax=0;
- min = Double.POSITIVE_INFINITY;
- max = Double.NEGATIVE_INFINITY;
- sum = 0.0;
- sqrsum = 0.0;
- n = 0;
-}
-
-
-// ======================== methods ===================================
-// ====================================================================
-
-
-/** Updates the statistics according to this element. It calls
-* <code>add(item,1)</code>.
-* @see #add(double,int) */
-public final void add( double item ) { add(item,1); }
-
-// --------------------------------------------------------------------
-
-/** Updates the statistics assuming element <code>item</code> is added
-* <code>k</code> times.*/
-public void add( double item, int k ) {
-
- if( item < min )
- {
- min = item;
- countmin = 0;
- }
- if( item == min ) countmin+=k;
- if( item > max )
- {
- max = item;
- countmax = 0;
- }
- if(item == max) countmax+=k;
- n+=k;
- if( k == 1 )
- {
- sum += item;
- sqrsum += item*item;
- }
- else
- {
- sum += item*k;
- sqrsum += item*item*k;
- }
-}
-
-// --------------------------------------------------------------------
-
-/** The number of data items processed so far */
-public int getN() { return n; }
-
-// --------------------------------------------------------------------
-
-/** The maximum of the data items */
-public double getMax() { return max; }
-
-// --------------------------------------------------------------------
-
-/** The minimum of the data items */
-public double getMin() { return min; }
-
-// --------------------------------------------------------------------
-
-/** Returns the number of data items whose value equals the maximum. */
-public int getMaxCount() { return countmax; }
-
-// --------------------------------------------------------------------
-
-/** Returns the number of data items whose value equals the minimum. */
-public int getMinCount() { return countmin; }
-
-// --------------------------------------------------------------------
-
-/** The sum of the data items */
-public double getSum() { return sum; }
-
-// --------------------------------------------------------------------
-
-/** The sum of the squares of the data items */
-public double getSqrSum() { return sqrsum; }
-
-// --------------------------------------------------------------------
-
-/** The average of the data items */
-public double getAverage() { return sum/n; }
-
-// --------------------------------------------------------------------
-
-/** The empirical variance of the data items. Guaranteed to be larger or
-equal to 0.0. If due to rounding errors the value becomes negative,
-it returns 0.0.*/
-public double getVar() {
-
- double var=
- (((double)n) / (n-1)) * (sqrsum/n - getAverage()*getAverage());
- return (var>=0.0?var:0.0);
- // XXX note that we have very little possibility to increase numeric
- // stability if this class is "greedy", ie, if it has no memory
- // In a more precise implementation we could delay the calculation of
- // statistics and store the data in some intelligent structure
-}
-
-// --------------------------------------------------------------------
-
-/** the empirical standard deviation of the data items */
-public double getStD() { return Math.sqrt(getVar()); }
-
-// --------------------------------------------------------------------
-
-/**
-* Prints the following quantities separated by spaces in a single line
-* in this order.
-* Minimum, maximum, number of items, average, variance, number of minimal
-* items, number of maximal items.
-*/
-public String toString() {
-
- return min+" "+max+" "+n+" "+sum/n+" "+getVar()+" "+
- countmin+" "+countmax;
-}
-
-}
-
+++ /dev/null
-/*
- * 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.util;
-
-/**
-* This class provides iterations over the set of integers [0...k-1].
-*/
-public interface IndexIterator {
-
- /**
- * This resets the iteration. The set of integers will be 0,..,k-1.
- */
- public void reset(int k);
-
- /**
- * Returns next index.
- */
- public int next();
-
- /**
- * Returns true if {@link #next} can be called at least one more time.
- * Note that {@link #next} can be called k times after {@link #reset}.
- */
- public boolean hasNext();
-}
-
+++ /dev/null
-/*
- * 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.util;
-
-import java.util.NoSuchElementException;
-
-/**
-* This class gives the linear order 0,1,etc or alternatively k-1, k-2, etc.,
-* depending on the constructor.
-*/
-public class LinearIterator implements IndexIterator {
-
-
-// ======================= private fields ============================
-// ===================================================================
-
-private final boolean reverse;
-
-private int len = 0;
-
-private int pointer = 0;
-
-
-// ======================= initialization ============================
-// ===================================================================
-
-
-/**
-* Construct an iterator for an empty set of numbers.
-* You have to call {@link #reset} to actually fully initialize the object.
-* The numbers returned by consecutive calls to {@link #next} are 0,1,...
-*/
-public LinearIterator() { reverse=false; }
-
-// -------------------------------------------------------------------
-
-/**
-* Construct an interator for an empty set of numbers.
-* You have to call {@link #reset} to actually fully initialize the object.
-* If parameter is true then the numbers returned by consecutive calls to
-* {@link #next} are k-1,k-2,..., otherwise 0,1,...
-*/
-public LinearIterator( boolean rev ) { reverse=rev; }
-
-
-// ======================= public methods ============================
-// ===================================================================
-
-
-public void reset(int k) {
-
- len = k;
- pointer = (reverse ? len-1 : 0);
-}
-
-// -------------------------------------------------------------------
-
-/**
-* Returns next index. The indices are returned in increasing or decreasing
-* order depending on the parameter given at construction time.
-*/
-public int next() {
-
- if( !hasNext() ) throw new NoSuchElementException();
-
- return (reverse ? pointer-- : pointer++);
-}
-
-// -------------------------------------------------------------------
-
-public boolean hasNext() { return (reverse ? pointer >= 0 : pointer < len); }
-
-// -------------------------------------------------------------------
-
-/*
-public static void main( String pars[] ) throws Exception {
-
- LinearIterator rp = new LinearIterator(pars[0].equals("rev"));
-
- int k = Integer.parseInt(pars[1]);
- rp.reset(k);
- while(rp.hasNext()) System.out.println(rp.next());
-
- System.out.println();
-
- k = Integer.parseInt(pars[2]);
- rp.reset(k);
- while(rp.hasNext()) System.out.println(rp.next());
- System.out.println(rp.next());
-}
-*/
-}
+++ /dev/null
-/*
- * 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.util;
-
-import java.util.ArrayList;
-import java.util.Collections;
-
-/**
- * This class adds the ability to retrieve the median element to the
- * {@link IncrementalStats} class. Note that this class actually stores all
- * the elements, so (unlike in its superclass) storage requirements depend
- * on the number of items processed.
- *
- * @author giampa
- */
-public class MedianStats extends IncrementalStats
-{
-
-/** Structure to store each entry. */
-private final ArrayList<Double> data=new ArrayList<Double>();
-
-/** Calls {@link #reset}. */
-public MedianStats()
-{
- reset();
-}
-
-/**
- * Retrieves the median in the current data collection.
- *
- * @return The current median value.
- */
-public double getMedian()
-{
- double result;
-
- if (data.isEmpty())
- throw new IllegalStateException("Data vector is empty!");
-
- // Sort the arraylist
- Collections.sort(data);
- if (data.size() % 2 != 0) { // odd number
- result = data.get(data.size() / 2);
- } else { // even number:
- double a = data.get(data.size() / 2);
- double b = data.get(data.size() / 2 - 1);
- result = (a + b) / 2;
- }
- return result;
-}
-
-public void add(double item, int k)
-{
- for (int i = 0; i < k; ++i) {
- super.add(item, 1);
- data.add(new Double(item));
- }
-}
-
-public void reset()
-{
- super.reset();
- if (data != null)
- data.clear();
-}
-
-
-public static void main( String[] args ) {
- MedianStats s = new MedianStats();
- for(int i=0; i<args.length; i++) s.add(Double.parseDouble(args[i]));
- System.out.println("Average: "+s.getAverage());
- System.out.println("Median: "+s.getMedian());
-}
-
-}
+++ /dev/null
-/*
- * 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.util;
-
-/**
- * This class provides extended statistical informations about the inspected
- * distribution. In particular, it provides functions to compute the skewness
- * (the 3rd degree moment) and the kurtosis (4th degree moment).
- *
- * @author Gian Paolo Jesi
- */
-public class MomentStats extends IncrementalStats {
-
- private double cubicsum, quadsum; // incremental sums
-
- /** Calls {@link #reset} */
- public MomentStats() {
- reset();
- }
-
- public void reset() {
- super.reset();
- cubicsum = quadsum = 0.0;
- }
-
- public void add(double item, int k) {
- for(int i=0; i<k; ++i)
- {
- super.add(item,1);
- cubicsum += item * item * item;
- quadsum += item * cubicsum;
- }
- }
-
- /** Outputs on a single line the superclass statistics postfixed by the
- * current skewness and kurtosis.
- */
- public String toString() {
- return super.toString()+" "+getSkewness()+" "+getKurtosis();
- }
-
- /** Computes the skewness on the node values distribution and
- * returns the asymmetry coefficient. It gives an indication about the
- * distribution symmetry compared to the average.
- *
- *@return The skewness value as a double.
- */
- public double getSkewness() {
- int n = this.getN();
- double m3 = (((double)n) / (n-1)) * (cubicsum/n - Math.pow(getAverage(), 3) );
- return ( m3 / Math.pow(getStD(), 3 ) );
- }
-
- /** Computes the kurtosis on the node values distribution and
- * returns the flatness coefficient. It gives an indication about the
- * distribution sharpness or flatness.
- *
- * @return The kurtosis momentus value as a double.
- */
- public double getKurtosis(){
- int n = this.getN();
- double m4 = (((double)n) / (n-1)) * (quadsum/n - Math.pow(getAverage(), 4) );
- return ( m4 / Math.pow(getStD(), 4) )-3;
- }
-
-}
+++ /dev/null
-/*
- * 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.util;
-
-import java.util.NoSuchElementException;
-import java.util.Random;
-
-/**
-* This class provides a random permutation of indexes. Useful for
-* random sampling without replacement.
-*/
-public class RandPermutation implements IndexIterator {
-
-
-// ======================= private fields ============================
-// ===================================================================
-
-
-private int[] buffer = null;
-
-private int len = 0;
-
-private int pointer = 0;
-
-private final Random r;
-
-
-// ======================= initialization ============================
-// ===================================================================
-
-
-/** Sets source of randomness to be used. You need to call
-* {@link #reset} to fully initialize the object.
-* @param r Source of randomness
-*/
-public RandPermutation( Random r ) { this.r=r; }
-
-// -------------------------------------------------------------------
-
-/** Sets source of randomness and initial size. It calls
-* {@link #setPermutation} to fully initialize the object with a
-* permuation ready to use.
-* @param r Source of randomness
-* @param k size of permutation
-*/
-public RandPermutation( int k, Random r ) {
-
- this.r=r;
- setPermutation(k);
-}
-
-
-// ======================= public methods ============================
-// ===================================================================
-
-
-/**
-* It calculates a random permutation of the integers from 0 to k-1.
-* The permutation can be read using method {@link #get}.
-* If the previous permutation was of the same length, it is more efficient.
-* Note that after calling this the object is reset, so {@link #next} can
-* be called k times, even if {@link #get} was called an arbitrary number of
-* times. Note however that mixing {@link #get} and {@link #next} results in
-* incorrect behavior for {@link #get} (but {@link #next} works fine).
-* The idea is to use this method only in connection with {@link #get}.
-*/
-public void setPermutation(int k) {
-
- reset(k);
-
- for(int i=len; i>1; i--)
- {
- int j = r.nextInt(i);
- int a = buffer[j];
- buffer[j] = buffer[i-1];
- buffer[i-1] = a;
- }
-}
-
-// -------------------------------------------------------------------
-
-/**
-* Returns the ith element of the permutation set by {@link #setPermutation}.
-* If {@link #next} is called after {@link #setPermutation} and before
-* this method, then the behavior of this method is unspecified.
-*/
-public int get(int i) {
-
- if( i >= len ) throw new IndexOutOfBoundsException();
- return buffer[i];
-}
-
-// -------------------------------------------------------------------
-
-/**
-* It initiates a random permutation of the integers from 0 to k-1.
-* It does not actually calculate the permutation.
-* The permutation can be read using method {@link #next}.
-* Calls to {@link #get} return undefined values, so {@link #next} must be used.
-* If the previous permutation was of the same length, it is more efficient.
-*/
-public void reset(int k) {
-
- pointer = k;
- if( len == k ) return;
-
- if( buffer == null || buffer.length < k )
- {
- buffer = new int[k];
- }
-
- len = k;
- for( int i=0; i<len; ++i ) buffer[i]=i;
-}
-
-// -------------------------------------------------------------------
-
-/** Next random sample without replacement */
-public int next() {
-
- if( pointer < 1 ) throw new NoSuchElementException();
-
- int j = r.nextInt(pointer);
- int a = buffer[j];
- buffer[j] = buffer[pointer-1];
- buffer[pointer-1] = a;
-
- return buffer[--pointer];
-}
-
-// -------------------------------------------------------------------
-
-public boolean hasNext() { return pointer > 0; }
-
-// -------------------------------------------------------------------
-
-/*
-public static void main( String pars[] ) throws Exception {
-
- RandPermutation rp = new RandPermutation(new Random());
-
- int k;
-
- k = Integer.parseInt(pars[0]);
- rp.setPermutation(k);
- for(int i=0; i<k; ++i) System.out.println(rp.get(i));
-
- System.out.println();
-
- k = Integer.parseInt(pars[1]);
- rp.reset(k);
- while(rp.hasNext()) System.out.println(rp.next());
-
- System.out.println();
-
- k = Integer.parseInt(pars[2]);
- rp.reset(k);
- while(rp.hasNext()) System.out.println(rp.next());
- System.out.println(rp.next());
-}
-*/
-}
+++ /dev/null
-/*
- * 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.util;
-
-import java.math.*;
-import java.util.*;
-
-import org.lsmp.djep.groupJep.*;
-
-import peersim.config.*;
-
-/**
- * This utility class can be used to parse range expressions. In particular,
- * it is used by {@link peersim.rangesim.RangeSimulator} to express ranges for
- * configuration properties.
- * <p>
- * The language for range expression is the following:
- * <pre>
- * [rangelist] := [range] | [range],[rangelist]
- * [range] := value | min:max | min:max|step |
- * min:max*|step
- * </pre>
- * where <tt>value</tt>, <tt>min</tt>, <tt>max</tt> and <tt>step</tt>
- * are numeric atoms that defines ranges.
- * <p>
- * For example, the following range expression:
- * <pre>
- * 5,9:11,13:17|2,32:128*|2
- * </pre>
- * corresponds to 5 (single value), 9-10-11 (range between 9 and 11,
- * default increment 1), 13-15-17 (range between 13 and 17, specified
- * step 2, 32-64-128 (range between 32 and 128, multiplicative step 2).
- *
- * @author Alberto Montresor
- * @version $Revision: 1.8 $
- */
-public class StringListParser
-{
-
-/** Disable instance construction */
-private StringListParser() { }
-
-/**
- * Parse the specified string.
- *
- * @param s the string to be parsed
- * @return an array of strings containing all the values defined by the
- * range string
- */
-public static String[] parseList(String s)
-{
- ArrayList<String> list = new ArrayList<String>();
- String[] tokens = s.split(",");
- for (int i = 0; i < tokens.length; i++) {
- parseItem(list, tokens[i]);
- }
- return list.toArray(new String[list.size()]);
-}
-
-private static void parseItem(List<String> list, String item)
-{
- String[] array = item.split(":");
- if (array.length == 1) {
- parseSingleItem(list, item);
- } else if (array.length == 2) {
- parseRangeItem(list, array[0], array[1]);
- } else {
- throw new IllegalArgumentException("Element " + item
- + "should be formatted as <start>:<stop> or <value>");
- }
-}
-
-private static void parseSingleItem(List<String> list, String item)
-{
- list.add(item);
-}
-
-private static void parseRangeItem(List<String> list, String start, String stop)
-{
- Number vstart;
- Number vstop;
- Number vinc;
- boolean sum;
-
- GroupJep jep = new GroupJep(new Operators());
- jep.parseExpression(start);
- vstart = (Number) jep.getValueAsObject();
- int pos = stop.indexOf("|*");
- if (pos >= 0) {
- // The string contains a multiplicative factor
- jep.parseExpression(stop.substring(0, pos));
- vstop = (Number) jep.getValueAsObject();
- jep.parseExpression(stop.substring(pos + 2));
- vinc = (Number) jep.getValueAsObject();
- sum = false;
- } else {
- pos = stop.indexOf("|");
- // The string contains an additive factor
- if (pos >= 0) {
- // The string contains just the final value
- jep.parseExpression(stop.substring(0, pos));
- vstop = (Number) jep.getValueAsObject();
- jep.parseExpression(stop.substring(pos + 1));
- vinc = (Number) jep.getValueAsObject();
- sum = true;
- } else {
- jep.parseExpression(stop);
- vstop = (Number) jep.getValueAsObject();
- vinc = BigInteger.ONE;
- sum = true;
- }
- }
-
- if (vstart instanceof BigInteger && vstart instanceof BigInteger && vinc instanceof BigInteger) {
- long vvstart = vstart.longValue();
- long vvstop = vstop.longValue();
- long vvinc = vinc.longValue();
- if (sum) {
- for (long i = vvstart; i <= vvstop; i += vvinc)
- list.add("" + i);
- } else {
- for (long i = vvstart; i <= vvstop; i *= vvinc)
- list.add("" + i);
- }
- } else {
- double vvstart = vstart.doubleValue();
- double vvstop = vstop.doubleValue();
- double vvinc = vinc.doubleValue();
- if (sum) {
- for (double i = vvstart; i <= vvstop; i += vvinc)
- list.add("" + i);
- } else {
- for (double i = vvstart; i <= vvstop; i *= vvinc)
- list.add("" + i);
- }
- }
-}
-
-/*
-public static void main(String[] args)
-{
- String[] ret = parseList(args[0]);
- for (int i = 0; i < ret.length; i++)
- System.out.print(ret[i] + " ");
- System.out.println("");
-}
-*/
-}
+++ /dev/null
-/*
- * 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.util;
-
-import java.util.NoSuchElementException;
-import java.util.Random;
-
-/**
-* This class provides a weighted random permutation of indexes.
-* Useful for weighted random sampling without replacement.
-* The next sample is taken according to the weights given as a parameter
-* to {@link #reset(int)}.
-* The weights work as follows.
-* The first sample is drawn according to the probability distribution
-* defined by the (normalized) weights.
-* After this the remaining k-1 elements and the associated k-1
-* (re-normalized) weights
-* define a new probability distribution, according to which the 2nd element
-* is drawn, and so on.
-*/
-public class WeightedRandPerm implements IndexIterator {
-
-
-// ======================= private fields ============================
-// ===================================================================
-
-/** Holds the weights that are used to initialize the permutation */
-private final double[] w;
-
-/** Holds the sum of the weights until the given index, inclusive. */
-private final double[] wsum;
-
-private int[] buffer = null;
-
-/** Working array for calculating the permutation */
-private double[] weights = null;
-
-private int len = 0;
-
-private int pointer = 0;
-
-private double sum = 0.0;
-
-private final Random r;
-
-
-// ======================= initialization ============================
-// ===================================================================
-
-
-/** Set the source of randomness to use and the weights. You need to call
-* {@link #reset} to fully initialize the object.
-* @param r source of randomness
-* @param weights The array that holds the weights for the calculation of the
-* permutation. The length of the array will be an upper bound on the
-* parameter {@link #reset} accepts. If {@link #reset} is called with a
-* parameter less than the length of weights, the prefix of the same length
-* is used.
-* The vector elements must be positive, that is, zero is not accepted either.
-*/
-public WeightedRandPerm( Random r, double[] weights ) {
-
- this.r=r;
- w = weights.clone();
- wsum = weights.clone();;
- this.weights = new double[w.length];
- buffer = new int[w.length];
-
- for(int i=0; i<w.length; ++i)
- {
- if( w[i] <= 0.0 ) throw new IllegalArgumentException(
- "weights should be positive: w["+i+"]="+w[i]);
- }
-
- for(int i=1; i<w.length; ++i) wsum[i]+=wsum[i-1];
-}
-
-
-// ======================= public methods ============================
-// ===================================================================
-
-
-/**
-* It initiates a random weighted permutation of the integeres from 0 to k-1.
-* It does not actually calculate the permutation.
-* The permutation can be read using method {@link #next}.
-* If the previous permutation was of the same length, it is more efficient.
-* The weights set at construction time work as follows.
-* The first sample is drawn according to the probability distribution
-* defined by the (normalized) weights.
-* After this the remaining k-1 elements and the associated k-1
-* (re-normalized) weights
-* define a new probability distribution, according to which the 2nd element
-* is drawn, and so on.
-* @param k the set is defined as 0,...,k-1
-*/
-public void reset(int k) {
-
- if( k<0 || k>w.length )
- throw new IllegalArgumentException(
- "k should be non-negative and <= "+w.length);
-
- pointer = k;
- sum = wsum[k-1];
-
- if( k != len )
- {
- // we need to initialize weights and buffer
- for(int i=0; i<k; ++i)
- {
- weights[i]=w[i];
- buffer[i]=i;
- }
- len=k;
- }
-}
-
-// -------------------------------------------------------------------
-
-/**
-* The first sample is drawn according to the probability distribution
-* defined by the (normalized) weights.
-* After this the remaining k-1 elements and the associated k-1
-* (re-normalized) weights
-* define a new probability distribution, according to which the 2nd element
-* is drawn, and so on.
-* @see #reset
-*/
-public int next() {
-
- if( pointer < 1 ) throw new NoSuchElementException();
-
- double d = sum*r.nextDouble();
- int i = pointer;
- double tmp = weights[i-1];
- while( tmp < d && i>1 ) tmp += weights[--i-1];
-
- // now i-1 is the selected element, we shift it to next position
- int a = buffer[i-1];
- double b = weights[i-1];
- buffer[i-1] = buffer[pointer-1];
- weights[i-1] = weights[pointer-1];
- buffer[pointer-1] = a;
- weights[pointer-1] = b;
- sum -= b;
-
- return buffer[--pointer];
-}
-
-// -------------------------------------------------------------------
-
-public boolean hasNext() { return pointer > 0; }
-
-// -------------------------------------------------------------------
-
-/*
-public static void main( String pars[] ) throws Exception {
-
-
- int k = pars.length;
- double w[] = new double[k];
- for(int i=0; i<k; ++i) w[i] = Double.parseDouble(pars[i]);
-
- WeightedRandPerm rp = new WeightedRandPerm(new Random(),w);
- rp.reset(k);
- for(int i=0; i<1000; ++i)
- {
- if(i%2==0) rp.reset(k);
- if(i%2==1) rp.reset(k-1);
- while(rp.hasNext()) System.out.print(rp.next()+" ");
- System.out.println();
- }
-
- System.out.println();
-}
-*/
-}
-
+++ /dev/null
-/*
- * 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.vector;
-
-import java.lang.reflect.*;
-import peersim.config.*;
-import peersim.core.*;
-
-/**
- * Vectors can be written through this class. Typically {@link Control} classes
- * use this to manipulate vectors.
- * <p>
- * The method to be used is specified at construction time.
- * For backward compatibility, if no method is specified, the method
- * <code>getValue</code> is used. In this way, protocols
- * implementing the {@link SingleValue} interface can be manipulated using the
- * old configuration syntax (i.e., without specifying the method).
- * <p>
- * Please refer to package {@link peersim.vector} for a detailed description of
- * the concept of protocol vector and the role of getters and setters.
- */
-public class Getter {
-
-// ============================ fields ===================================
-// =======================================================================
-
-private final String protocol;
-private final String methodn;
-private final String prefix;
-
-/** Identifier of the protocol that defines the vector */
-private int pid;
-
-/** Getter method name */
-private String methodName;
-
-/** Getter method */
-private Method method = null;
-
-/** Parameter type of getter method */
-private Class type;
-
-
-// ========================== initialization =============================
-// =======================================================================
-
-
-/**
- * Constructs a Getter class based on the configuration. Note that the
- * actual initialization is delayed until the first access to the class,
- * so that if a class is not used, no unnecessary error messages and exceptions
- * are generated.
- * @param prefix the configuration prefix to use when reading the configuration
- * @param protocol the configuration parameter name that contains
- * the protocol we want to manipulate using a getter method.
- * The parameter <code>prefix + "." + protocol</code> is read.
- * @param methodn the configuration parameter name that contains the getter
- * method name.
- * The parameter <code>prefix + "." + methodn</code> is read, with the default
- * value <code>getValue</code>.
- */
-public Getter(String prefix, String protocol, String methodn) {
-
- this.prefix=prefix;
- this.protocol=protocol;
- this.methodn=methodn;
-}
-
-// --------------------------------------------------------------------------
-
-/** Performs actual initialization */
-private void init() {
-
- if( method!=null) return;
-
- // Read configuration parameter
- pid = Configuration.getPid(prefix + "." + protocol);
- methodName = Configuration.getString(prefix+"."+methodn,"getValue");
- // Search the method
- Class clazz = Network.prototype.getProtocol(pid).getClass();
- try {
- method = GetterSetterFinder.getGetterMethod(clazz, methodName);
- } catch (NoSuchMethodException e) {
- throw new IllegalParameterException(prefix + "." +
- methodn, e+"");
- }
- // Obtain the type of the field
- type = GetterSetterFinder.getGetterType(method);
-}
-
-
-// =============================== methods =============================
-// =====================================================================
-
-/**
-* @return type of return value of getter method
-*/
-public Class getType() {
-
- init();
- return type;
-}
-
-// --------------------------------------------------------------------------
-
-/**
-* Gets the given value as a Number.
-* @param n The node to get the value on. The protocol is defined
-* by {@link #pid}.
-* @return the read value.
-*/
-public Number get(Node n) {
-
- init();
-
- try
- {
- Object ret =method.invoke(n.getProtocol(pid));
- if (ret instanceof Boolean)
- return ((Boolean) ret) ? 1 : 0;
- else
- return (Number) ret;
- }
- catch (Exception e)
- {
- throw new RuntimeException("While using getter "+methodName,e);
- }
-}
-
-// --------------------------------------------------------------------------
-
-/**
-* Gets the given integer value.
-* @param n The node to get the value on. The protocol is defined
-* by {@link #pid}.
-* @return the read value.
-*/
-public long getLong(Node n) {
-
- init();
-
- if(type==long.class || type==int.class)
- {
- try
- {
- return ((Number)
- method.invoke(n.getProtocol(pid))).longValue();
- }
- catch (Exception e)
- {
- throw new RuntimeException(
- "While using getter "+methodName,e);
- }
- }
- else throw new RuntimeException("type has to be int or long");
-}
-
-// --------------------------------------------------------------------------
-
-/**
-* Gets the given real value.
-* @param n The node to get the value on. The protocol is defined
-* by {@link #pid}.
-* @return the read value.
-*/
-public double getDouble(Node n) {
-
- init();
-
- if(type==double.class || type==float.class)
- {
- try
- {
- return ((Number)
- method.invoke(n.getProtocol(pid))).doubleValue();
- }
- catch (Exception e)
- {
- throw new RuntimeException(
- "While using getter "+methodName,e);
- }
- }
- else throw new RuntimeException(
- "type has to be double or float");
-}
-
-// --------------------------------------------------------------------------
-
-/**
-* Gets the given value as a Number.
-* @param i The index of the node to get the value on in the network.
-* The protocol is defined
-* by {@link #pid}.
-* @return the read value.
-*/
-public Number get(int i) { return get(Network.get(i)); }
-
-// --------------------------------------------------------------------------
-
-/**
-* Gets the given integer value.
-* @param i The index of the node to get the value on in the network.
-* The protocol is defined
-* by {@link #pid}.
-* @return the read value.
-*/
-public long getLong(int i) { return getLong(Network.get(i)); }
-
-// --------------------------------------------------------------------------
-
-/**
-* Gets the given real value.
-* @param i The index of the node to get the value on in the network.
-* The protocol is defined
-* by {@link #pid}.
-* @return the read value.
-*/
-public double getDouble(int i) { return getDouble(Network.get(i)); }
-
-}
-
+++ /dev/null
-/*
- * 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.vector;
-
-import java.lang.reflect.*;
-import java.util.*;
-
-/**
- * This utility class can be used to obtain get/set methods from classes. In
- * particular, it is used in the vector package to locate get/set methods for
- * observing and modifying protocol fields.
- * Please refer to package {@link peersim.vector} for a definition of
- * getter and setter methods.
- */
-class GetterSetterFinder
-{
-
-//--------------------------------------------------------------------------
-
-/**
- * Search a getter method in the specified class. It succeeds only of there
- * is exactly one method with the given name that is a getter method.
- * Please refer to package {@link peersim.vector} for a definition of
- * getter methods.
- *
- * @param clazz
- * the class where to find get/set method
- * @param methodName
- * the method to be searched
- * @return the requested method
- */
-public static Method getGetterMethod(Class clazz, String methodName)
- throws NoSuchMethodException
-{
- // Search methods
- Method[] methods = clazz.getMethods();
- ArrayList<Method> list = new ArrayList<Method>();
- for (Method m: methods) {
- if (m.getName().equals(methodName)) {
- list.add(m);
- }
- }
- if (list.size() == 0) {
- throw new NoSuchMethodException("No getter method for method "
- + methodName + " in class " + clazz.getName());
- } else if (list.size() > 1) {
- throw new NoSuchMethodException("Multiple getter for method "
- + methodName + " in class " + clazz.getName());
- }
-
- // Found a single method with the right name; check if
- // it is a gettter.
- Method method = list.get(0);
- Class[] pars = method.getParameterTypes();
- if (pars.length > 0) {
- throw new NoSuchMethodException(method.getName() + " of class "
- + clazz.getName()
- + " is not a valid getter method: "+
- "its argument list is not empty");
- }
-
- Class ret = method.getReturnType();
- if ( !( ret==int.class || ret==long.class ||
- ret==double.class || ret==float.class || ret==boolean.class)
- ) {
- throw new NoSuchMethodException(method.getName() + " of class "
- + clazz.getName() + " is not a valid getter method: "+
- "it should have a return type of int, long, short or double");
- }
-
- return method;
-}
-
-//--------------------------------------------------------------------------
-
-/**
- * Search a setter method in the specified class.
- * It succeeds only of there
- * is exactly one method with the given name that is a setter method.
- * Please refer to package {@link peersim.vector} for a definition of
- * setter methods.
- * @param clazz
- * the class where to find get/set method
- * @param methodName
- * the method to be searched
- * @return the requested method, if it fully conforms to the definition of
- * the setter methods.
- */
-public static Method getSetterMethod(Class clazz, String methodName)
- throws NoSuchMethodException
-{
- // Search methods
- Method[] methods = clazz.getMethods();
- ArrayList<Method> list = new ArrayList<Method>();
- for (Method m: methods) {
- if (m.getName().equals(methodName)) {
- list.add(m);
- }
- }
-
- if (list.size() == 0) {
- throw new NoSuchMethodException("No setter method for method "
- + methodName + " in class " + clazz.getName());
- } else if (list.size() > 1) {
- throw new NoSuchMethodException("Multiple setter for method "
- + methodName + " in class " + clazz.getName());
- }
-
- // Found a single method with the right name; check if
- // it is a setter.
- Method method = list.get(0);
- Class[] pars = method.getParameterTypes();
- if ( pars.length != 1 ||
- !( pars[0]==int.class || pars[0]==long.class ||
- pars[0]==double.class || pars[0]==float.class )
- ) {
- throw new NoSuchMethodException(method.getName() + " of class "
- + clazz.getName()
- + " is not a valid setter method: "+
- "it should have exactly one argument of type "+
- "int, long, short or double");
- }
-
- Class ret = method.getReturnType();
- if (!ret.equals(void.class)) {
- throw new NoSuchMethodException(method.getName() + " of class "
- + clazz.getName() +
- " is not a valid setter method; it returns a value");
- }
-
- return method;
-}
-
-//--------------------------------------------------------------------------
-
-
-/**
- * Returns the field type for the specified getter.
- */
-public static Class getGetterType(Method m)
-{
- return m.getReturnType();
-}
-
-//--------------------------------------------------------------------------
-
-/**
- * Returns the field type for the specified setter.
- */
-public static Class getSetterType(Method m)
-{
- Class[] pars = m.getParameterTypes();
- return pars[0];
-}
-
-//--------------------------------------------------------------------------
-
-}
+++ /dev/null
-/*
- * 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.vector;
-
-import java.io.*;
-import java.util.*;
-import peersim.config.*;
-import peersim.core.*;
-
-/**
- * Initializes a protocol vector from data read from a file.
- * The file format is as follows:
- * lines starting with # or lines that contain only
- * whitespace are ignored.
- * From the rest of the lines the first field separated by whitespace is
- * read. Only the first field is read from each line, the rest of the line
- * is ignored.
- * The file can contain more values than necessary but
- * enough values must be present.
- * @see VectControl
- * @see peersim.vector
- */
-public class InitVectFromFile extends VectControl
-{
-
-// --------------------------------------------------------------------------
-// Parameter names
-// --------------------------------------------------------------------------
-
-/**
- * The filename to load links from.
- * @config
- */
-private static final String PAR_FILE = "file";
-
-// --------------------------------------------------------------------------
-// Fields
-// --------------------------------------------------------------------------
-
-/** The file to be read */
-private final String file;
-
-// --------------------------------------------------------------------------
-// Initialization
-// --------------------------------------------------------------------------
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param prefix the configuration prefix for this class
- */
-public InitVectFromFile(String prefix)
-{
- super(prefix);
- file = Configuration.getString(prefix + "." + PAR_FILE);
-}
-
-// --------------------------------------------------------------------------
-// Methods
-// --------------------------------------------------------------------------
-
-/**
- * Initializes values from a file.
- * The file format is as follows:
- * lines starting with # or lines that contain only
- * whitespace are ignored.
- * From the rest of the lines the first field separated by whitespace is
- * read. Only the first field is read from each line, the rest of the line
- * is ignored.
- * The file can contain more values than necessary but
- * enough values must be present.
- * @throws RuntimeException if the file cannot be read or contains too few
- * values
- * @return always false
- */
-public boolean execute() {
-
- int i = 0;
-
-try {
- FileReader fr = new FileReader(file);
- LineNumberReader lnr = new LineNumberReader(fr);
- String line;
- while ((line = lnr.readLine()) != null && i < Network.size()) {
- if (line.startsWith("#"))
- continue;
- StringTokenizer st = new StringTokenizer(line);
- if (!st.hasMoreTokens())
- continue;
- if( setter.isInteger() )
- setter.set(i,Long.parseLong(st.nextToken()));
- else setter.set(i,Double.parseDouble(st.nextToken()));
- i++;
- }
- lnr.close();
-}
-catch(IOException e)
-{
- throw new RuntimeException("Unable to read file: " + e);
-}
-
- if (i < Network.size())
- throw new RuntimeException(
- "Too few values in file '" + file + "' (only "
- + i + "); we need " + Network.size() + ".");
-
- return false;
-}
-
-// --------------------------------------------------------------------------
-
-}
+++ /dev/null
-/*
- * 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.vector;
-
-import peersim.config.*;
-import peersim.core.*;
-
-/**
- * Initializes a protocol vector with values in the range [{@value #PAR_MIN},
- * {@value #PAR_MAX}] (inclusive both ends), linearly increasing.
- * @see VectControl
- * @see peersim.vector
- */
-public class LinearDistribution extends VectControl
-{
-
-//--------------------------------------------------------------------------
-//Parameters
-//--------------------------------------------------------------------------
-
-/**
- * Upper end of the interval..
- * @config
- */
-private static final String PAR_MAX = "max";
-
-/**
- * Lower end of the interval. Defaults to -{@value #PAR_MAX}.
- * @config
- */
-private static final String PAR_MIN = "min";
-
-// --------------------------------------------------------------------------
-// Fields
-// --------------------------------------------------------------------------
-
-/** Minimum value */
-private final Number min;
-
-/** Maximum value */
-private final Number max;
-
-/** Step value */
-private final double step;
-
-// --------------------------------------------------------------------------
-// Initialization
-// --------------------------------------------------------------------------
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param prefix the configuration prefix for this class
- */
-public LinearDistribution(String prefix)
-{
- super(prefix);
-
- // Read parameters based on type
- if (setter.isInteger()) {
- max=Long.valueOf(Configuration.getLong(prefix + "." + PAR_MAX));
- min=Long.valueOf(Configuration.getLong(prefix + "." + PAR_MIN,
- -max.longValue()));
- step= (max.longValue()-min.longValue())/
- ((double)(Network.size()-1));
- } else { // we know it's double or float
- max = new Double(Configuration.getDouble(prefix+"."+PAR_MAX));
- min = new Double(Configuration.getDouble(prefix+"."+PAR_MIN,
- -max.doubleValue()));
- step= (max.doubleValue()-min.doubleValue())/(Network.size()-1);
- }
-}
-
-// --------------------------------------------------------------------------
-// Methods
-// --------------------------------------------------------------------------
-
-/**
- * Initializes a protocol vector with values in the range [{@value #PAR_MIN},
- * {@value #PAR_MAX}] (inclusive both ends), linearly increasing.
- * @return always false
- */
-public boolean execute() {
-
- if ( setter.isInteger() )
- {
- for(int i=0; i<Network.size(); ++i)
- {
- // we avoid the entire expression being cast to double
- setter.set(i,Math.round(i*step)+min.longValue());
- }
- }
- else
- {
- for(int i=0; i<Network.size(); ++i)
- {
- setter.set(i,i*step+min.doubleValue());
- }
- }
-
- return false;
-}
-
-
-}
-
-
+++ /dev/null
-/*
- * 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.vector;
-
-import peersim.config.*;
-import peersim.core.*;
-
-/**
- * Normalizes the values of a protocol vector.
- * The normalization is based on the L1 norm, that is, the sum of the
- * absolute values of the vector elements. Parameter {@value #PAR_L1} defines
- * the L1 norm that the vector will have after normalization.
- * @see VectControl
- * @see peersim.vector
- */
-public class Normalizer extends VectControl
-{
-
-// --------------------------------------------------------------------------
-// Parameters
-// --------------------------------------------------------------------------
-
-/**
- * The L1 norm (sum of absolute values) to normalize to. After the operation the
- * L1 norm will be the value given here. Defaults to 1.
- * @config
- */
-private static final String PAR_L1 = "l1";
-
-
-// --------------------------------------------------------------------------
-// Fields
-// --------------------------------------------------------------------------
-
-/** L1 norm */
-private final double l1;
-
-
-// --------------------------------------------------------------------------
-// Initialization
-// --------------------------------------------------------------------------
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param prefix the configuration prefix for this class
- */
-public Normalizer(String prefix)
-{
- super(prefix);
- l1 = Configuration.getDouble(prefix + "." + PAR_L1, 1);
-
- if( setter.isInteger() )
- throw new IllegalParameterException(prefix + "." + PAR_METHOD,
- "setter value must be floating point, instead of "+
- setter.getType());
-
- if( setter.getType() != getter.getType() )
- throw new IllegalParameterException(prefix + "." + PAR_GETTER,
- "getter and setter must have the same numeric type, "+
- "but we have "+setter.getType()+" and "+getter.getType());
-}
-
-//--------------------------------------------------------------------------
-//Methods
-//--------------------------------------------------------------------------
-
-/**
- * Makes the sum of the absolute values (L1 norm) equal to the value
- * given in the configuration parameter {@value #PAR_L1}. If the value is
- * negative, the L1 norm will be the absolute value and the vector elements
- * change sign.
- * @return always false
- */
-public boolean execute() {
-
- double sum = 0.0;
- for (int i = 0; i < Network.size(); ++i)
- {
- sum += getter.getDouble(i);
- }
- if (sum == 0.0)
- {
- throw new
- RuntimeException("Attempted to normalize all zero vector.");
- }
- double factor = l1 / sum;
- for (int i = 0; i < Network.size(); ++i)
- {
- double val = getter.getDouble(i)*factor;
- setter.set(i,val);
- }
- return false;
-}
-
-//--------------------------------------------------------------------------
-
-}
+++ /dev/null
-/*
- * 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.vector;
-
-import peersim.config.*;
-import peersim.core.*;
-
-
-/**
- * Initializes the values so that {@value #PAR_PEAKS} nodes have value
- * {@value #PAR_VALUE}/{@value #PAR_PEAKS}, the rest {@value #PAR_LVALUE}
- * (zero by default).
- * @see VectControl
- * @see peersim.vector
- */
-public class PeakDistribution extends VectControl
-{
-
-// --------------------------------------------------------------------------
-// Parameters
-// --------------------------------------------------------------------------
-
-/**
- * The sum of values in the system, to be equally distributed between peak
- * nodes.
- * @config
- */
-private static final String PAR_VALUE = "value";
-
-/**
- * The value for the nodes that are not peaks. This parameter is optional,
- * by default, the nodes that are
- * not peaks are set to zero. This value overrides that behavior.
- * @config
- */
-private static final String PAR_LVALUE = "background";
-
-/**
- * The number of peaks in the system. If this value is greater than or equal to
- * 1, it is interpreted as the actual number of peaks. If it is included in
- * the range [0, 1] it is interpreted as a percentage with respect to the
- * current network size. Defaults to 1.
- * @config
- */
-private static final String PAR_PEAKS = "peaks";
-
-
-// --------------------------------------------------------------------------
-// Fields
-// --------------------------------------------------------------------------
-
-/** Total load */
-private final Number lvalue;
-
-/** Total load */
-private final Number value;
-
-/** Number of peaks */
-private final double peaks;
-
-// --------------------------------------------------------------------------
-// Initialization
-// --------------------------------------------------------------------------
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param prefix the configuration prefix for this class
- */
-public PeakDistribution(String prefix)
-{
- super(prefix);
-
- peaks = Configuration.getDouble(prefix+"."+PAR_PEAKS, 1);
-
- if( setter.isInteger() )
- {
- value=Long.valueOf(Configuration.getLong(prefix+"."+PAR_VALUE));
- lvalue=Long.valueOf(Configuration.getLong(prefix+"."+PAR_LVALUE,0));
- }
- else
- {
- value = new Double(Configuration.getDouble(prefix + "." +
- PAR_VALUE));
- lvalue = new Double(Configuration.getDouble(prefix + "." +
- PAR_LVALUE,0));
- }
-}
-
-// --------------------------------------------------------------------------
-// Methods
-// --------------------------------------------------------------------------
-
-/**
- * Initializes the values so that {@value #PAR_PEAKS} nodes have value
- * {@value #PAR_VALUE}/{@value #PAR_PEAKS}, the rest zero.
- * @return always false
- */
-public boolean execute()
-{
- int pn = (peaks < 1 ? (int) (peaks*Network.size()) : (int) peaks);
-
- if( setter.isInteger() )
- {
- long v = value.longValue()/pn;
- long lv = lvalue.longValue();
- for (int i=0; i < pn; i++) setter.set(i, v);
- for (int i=pn; i < Network.size(); i++) setter.set(i,lv);
- }
- else
- {
- double v = value.doubleValue()/pn;
- double lv = lvalue.doubleValue();
- for (int i=0; i < pn; i++) setter.set(i, v);
- for (int i=pn; i < Network.size(); i++) setter.set(i,lv);
- }
-
- return false;
-}
-
-// --------------------------------------------------------------------------
-
-}
+++ /dev/null
-/*
- * 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.vector;
-
-import java.lang.reflect.*;
-import peersim.config.*;
-import peersim.core.*;
-
-/**
- * Vectors can be written through this class. Typically {@link Control} classes
- * use this to manipulate vectors.
- * <p>
- * The method to be used is specified at construction time.
- * For backward compatibility, if no method is specified, the method
- * <code>setValue</code> is used. In this way, protocols
- * implementing the {@link SingleValue} interface can be manipulated using the
- * old configuration syntax (i.e., without specifying the method).
- * <p>
- * Please refer to package {@link peersim.vector} for a detailed description of
- * the concept of protocol vector and the role of getters and setters.
- */
-public class Setter {
-
-// ============================ fields ===================================
-// =======================================================================
-
-private final String protocol;
-private final String methodn;
-private final String prefix;
-
-/** Identifier of the protocol that defines the vector */
-private int pid;
-
-/** Setter method name */
-private String methodName;
-
-/** Setter method */
-private Method method=null;
-
-/** Parameter type of setter method */
-private Class type;
-
-
-// ========================== initialization =============================
-// =======================================================================
-
-
-/**
- * Constructs a Setter class based on the configuration.
- * Note that the
- * actual initialization is delayed until the first access to the class,
- * so that if a class is not used, no unnecessary error messages and exceptions
- * are generated.
- * @param prefix the configuration prefix to use when reading the configuration
- * @param protocol the configuration parameter name that contains
- * the protocol we want to manipulate using a setter method.
- * The parameter <code>prefix + "." + protocol</code> is read.
- * @param methodn the configuration parameter name that contains the setter
- * method name.
- * The parameter <code>prefix + "." + methodn</code> is read, with the default
- * value <code>setValue</code>.
- */
-public Setter(String prefix, String protocol, String methodn) {
-
- this.prefix=prefix;
- this.protocol=protocol;
- this.methodn=methodn;
-}
-
-// --------------------------------------------------------------------------
-
-private void init() {
-
- if( method!=null) return;
-
- // Read configuration parameter
- pid = Configuration.getPid(prefix + "." + protocol);
- methodName = Configuration.getString(prefix+"."+methodn,"setValue");
- // Search the method
- Class clazz = Network.prototype.getProtocol(pid).getClass();
- try {
- method = GetterSetterFinder.getSetterMethod(clazz, methodName);
- } catch (NoSuchMethodException e) {
- throw new IllegalParameterException(prefix + "." +
- methodn, e+"");
- }
- // Obtain the type of the field
- type = GetterSetterFinder.getSetterType(method);
-}
-
-
-// =============================== methods =============================
-// =====================================================================
-
-
-/**
-* @return type of parameter of setter method
-*/
-public Class getType() {
-
- init();
- return type;
-}
-
-// --------------------------------------------------------------------------
-
-/**
-* @return true if the setter type is long or int
-*/
-public boolean isInteger() {
-
- init();
- return type==long.class || type==int.class;
-}
-
-// --------------------------------------------------------------------------
-
-/**
-* Sets the given integer value.
-* @param n The node to set the value on. The protocol is defined
-* by {@link #pid}.
-* @param val the value to set.
-*/
-public void set(Node n, long val) {
-
- init();
-
- try
- {
- if(type==long.class)
- {
- method.invoke(n.getProtocol(pid),val);
- return;
- }
- if(type==int.class)
- {
- method.invoke(n.getProtocol(pid),(int)val);
- return;
- }
- }
- catch (Exception e)
- {
- throw new RuntimeException("While using setter "+methodName,e);
-
- }
-
- throw new RuntimeException("type has to be int or long");
-}
-
-// --------------------------------------------------------------------------
-
-/**
-* Sets the given real value.
-* @param n The node to set the value on. The protocol is defined
-* by {@link #pid}.
-* @param val the value to set.
-*/
-public void set(Node n, double val) {
-
- init();
-
- try
- {
- if(type==double.class)
- {
- method.invoke(n.getProtocol(pid),val);
- return;
- }
- if(type==float.class)
- {
- method.invoke(n.getProtocol(pid),(float)val);
- return;
- }
- }
- catch (Exception e)
- {
- throw new RuntimeException("While using setter "+methodName,e);
- }
-
- throw new RuntimeException("type has to be double or float");
-}
-
-// --------------------------------------------------------------------------
-
-/**
-* Sets the given integer value.
-* @param i The index of the node to set the value on in the network.
-* The protocol is defined
-* by {@link #pid}.
-* @param val the value to set.
-*/
-public void set(int i, long val) { set(Network.get(i),val); }
-
-// --------------------------------------------------------------------------
-
-/**
-* Sets the given real value.
-* @param i The index of the node to set the value on in the network.
-* The protocol is defined
-* by {@link #pid}.
-* @param val the value to set.
-*/
-public void set(int i, double val) { set(Network.get(i),val); }
-
-}
-
+++ /dev/null
-/*
- * 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.vector;
-
-/**
-* The implementor class has a single parameter. This interface
-* provides access to that parameter.
-*/
-public interface SingleValue {
-
-/**
- * Returns the value of the parameter hold by the implementor
- * of this interface.
- */
-public double getValue();
-
-/**
- * Modifies the value of the parameter hold by the implementor
- * of this interface.
- */
-public void setValue(double value);
-
-}
-
+++ /dev/null
-/*
- * 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.vector;
-
-import peersim.core.*;
-import java.util.*;
-
-/**
- * This comparator class compares two node objects based on the value
- * maintained by one of its protocols. The protocol must implement the
- * {@link SingleValue} interface; its identifier has to be specified when a
- * new comparator is built.
- *
- * @author Alberto Montresor
- * @version $Revision: 1.4 $
- */
-public class SingleValueComparator implements Comparator
-{
-
-/** Protocol to be be compared */
-private int pid;
-
-/**
- * Builds a new comparator that compares the double values maintained
- * by protocol identified by <code>pid</code>.
- */
-public SingleValueComparator(int pid) { this.pid = pid; }
-
-/**
- * Compares the values of two protocols. The parameters must have dynamic type
- * {@link Node}. The protocol {@link #pid} is accessed on both nodes. These
- * protocols have to implement the {@link SingleValue} interface. The values
- * held by these protocol instances are then compared.
- */
-public int compare(Object o1, Object o2)
-{
- SingleValue s1 = (SingleValue) ((Node) o1).getProtocol(pid);
- SingleValue s2 = (SingleValue) ((Node) o2).getProtocol(pid);
- return (int) (s1.getValue() - s2.getValue());
-}
-
-}
+++ /dev/null
-/*
- * 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.vector;
-
-import peersim.core.*;
-
-/**
- * The task of this protocol is to store a single double value and make it
- * available through the {@link SingleValue} interface.
- *
- * @author Alberto Montresor
- * @version $Revision: 1.6 $
- */
-public class SingleValueHolder
-implements SingleValue, Protocol
-{
-
-//--------------------------------------------------------------------------
-//Fields
-//--------------------------------------------------------------------------
-
-/** Value held by this protocol */
-protected double value;
-
-
-//--------------------------------------------------------------------------
-//Initialization
-//--------------------------------------------------------------------------
-
-/**
- * Does nothing.
- */
-public SingleValueHolder(String prefix)
-{
-}
-
-//--------------------------------------------------------------------------
-
-/**
- * Clones the value holder.
- */
-public Object clone()
-{
- SingleValueHolder svh=null;
- try { svh=(SingleValueHolder)super.clone(); }
- catch( CloneNotSupportedException e ) {} // never happens
- return svh;
-}
-
-//--------------------------------------------------------------------------
-//methods
-//--------------------------------------------------------------------------
-
-/**
- * @inheritDoc
- */
-public double getValue()
-{
- return value;
-}
-
-//--------------------------------------------------------------------------
-
-/**
- * @inheritDoc
- */
-public void setValue(double value)
-{
- this.value = value;
-}
-
-//--------------------------------------------------------------------------
-
-/**
- * Returns the value as a string.
- */
-public String toString() { return ""+value; }
-
-}
+++ /dev/null
-/*
- * 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.vector;
-
-import peersim.config.*;
-import peersim.core.*;
-import peersim.util.*;
-
-/**
-* Print statistics over a vector. The vector is defined by a protocol,
-* specified by {@value #PAR_PROT}, that has to implement
-* {@link SingleValue}.
-* Statistics printed are: min, max, number of samples, average, variance,
-* number of minimal instances, number of maximal instances (using
-* {@link IncrementalStats#toString}).
-* @see IncrementalStats
-*/
-public class SingleValueObserver implements Control {
-
-
-//--------------------------------------------------------------------------
-//Parameters
-//--------------------------------------------------------------------------
-
-/**
- * The parameter used to determine the accuracy
- * (standard deviation) before stopping the simulation. If not
- * defined, a negative value is used which makes sure the observer
- * does not stop the simulation.
- * @see #execute
- * @config
- */
-private static final String PAR_ACCURACY = "accuracy";
-
-/**
- * The protocol to operate on.
- * @config
- */
-private static final String PAR_PROT = "protocol";
-
-
-//--------------------------------------------------------------------------
-// Fields
-//--------------------------------------------------------------------------
-
-/** The name of this observer in the configuration */
-private final String name;
-
-/** Accuracy for standard deviation used to stop the simulation */
-private final double accuracy;
-
-/** Protocol identifier */
-private final int pid;
-
-
-//--------------------------------------------------------------------------
-// Constructor
-//--------------------------------------------------------------------------
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param name the configuration prefix for this class
- */
-public SingleValueObserver(String name)
-{
- this.name = name;
- accuracy = Configuration.getDouble(name + "." + PAR_ACCURACY, -1);
- pid = Configuration.getPid(name + "." + PAR_PROT);
-}
-
-
-//--------------------------------------------------------------------------
-// Methods
-//--------------------------------------------------------------------------
-
-/**
-* Print statistics over a vector. The vector is defined by a protocol,
-* specified by {@value #PAR_PROT}, that has to implement
-* {@link SingleValue}.
-* Statistics printed are: min, max, number of samples, average, variance,
-* number of minimal instances, number of maximal instances (using
-* {@link IncrementalStats#toString}).
-* @return true if the standard deviation is below the value of
- * {@value #PAR_ACCURACY}, and the time of the simulation is larger then zero
- * (i.e. it has started).
- */
-public boolean execute()
-{
- IncrementalStats stats = new IncrementalStats();
-
- /* Compute max, min, average */
- for (int i = 0; i < Network.size(); i++)
- {
- SingleValue v = (SingleValue)Network.get(i).getProtocol(pid);
- stats.add( v.getValue() );
- }
-
- /* Printing statistics */
- System.out.println(name+": "+stats);
-
- /* Terminate if accuracy target is reached */
- return (stats.getStD()<=accuracy && CommonState.getTime()>0);
-}
-
-//--------------------------------------------------------------------------
-
-}
+++ /dev/null
-/*
- * 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.vector;
-
-
-/**
- * Do testing the vector package.
- */
-public class TestVectors extends SingleValueHolder
-{
-
-//--------------------------------------------------------------------------
-//Fields
-//--------------------------------------------------------------------------
-
-/** Value held by this protocol */
-protected float fvalue;
-
-/** Value held by this protocol */
-protected int ivalue;
-
-/** Value held by this protocol */
-protected long lvalue;
-
-
-//--------------------------------------------------------------------------
-//Initialization
-//--------------------------------------------------------------------------
-
-/**
- * Builds a new (not initialized) value holder.
- * Calls super constructor.
- */
-public TestVectors(String prefix) { super(prefix); }
-
-//--------------------------------------------------------------------------
-//methods
-//--------------------------------------------------------------------------
-
-/**
- *
- */
-public int getIValue() { return ivalue; }
-
-//--------------------------------------------------------------------------
-
-/**
- *
- */
-public void setIValue(int value) { ivalue = value; }
-
-//--------------------------------------------------------------------------
-
-/**
- *
- */
-public float getFValue() { return fvalue; }
-
-//--------------------------------------------------------------------------
-
-/**
- *
- */
-public void setFValue(float value) { fvalue = value; }
-
-//--------------------------------------------------------------------------
-
-/**
- *
- */
-public long getLValue() { return lvalue; }
-
-//--------------------------------------------------------------------------
-
-/**
- *
- */
-public void setLValue(long value) { lvalue = value; }
-
-//--------------------------------------------------------------------------
-
-/**
- * Returns the value as a string.
- */
-public String toString() { return value+" "+fvalue+" "+ivalue+" "+lvalue; }
-
-}
-
+++ /dev/null
-/*
- * 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.vector;
-
-import peersim.config.*;
-import peersim.core.*;
-import peersim.dynamics.*;
-
-/**
- * Initializes the values drawing uniform random samples from the range
- * [{@value #PAR_MIN}, {@value #PAR_MAX}[.
- * @see VectControl
- * @see peersim.vector
- */
-public class UniformDistribution extends VectControl implements NodeInitializer
-{
-
-//--------------------------------------------------------------------------
-//Parameter names
-//--------------------------------------------------------------------------
-
-/**
- * The upper bound of the uniform random variable, exclusive.
- * @config
- */
-private static final String PAR_MAX = "max";
-
-/**
- * The lower bound of the uniform
- * random variable, inclusive. Defaults to -{@value #PAR_MAX}.
- * @config
- */
-private static final String PAR_MIN = "min";
-
-// --------------------------------------------------------------------------
-// Fields
-// --------------------------------------------------------------------------
-
-/** Minimum value */
-private final Number min;
-
-/** Maximum value */
-private final Number max;
-
-// --------------------------------------------------------------------------
-// Initialization
-// --------------------------------------------------------------------------
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param prefix the configuration prefix for this class
- */
-public UniformDistribution(String prefix)
-{
- super(prefix);
-
- // Read parameters based on type
- if (setter.isInteger()) {
- max=Long.valueOf(Configuration.getLong(prefix + "." + PAR_MAX));
- min=Long.valueOf(Configuration.getLong(prefix + "." + PAR_MIN,
- -max.longValue()));
- } else { // we know it's double or float
- max = new Double(Configuration.getDouble(prefix+"."+PAR_MAX));
- min = new Double(Configuration.getDouble(prefix+"."+PAR_MIN,
- -max.doubleValue()));
- }
-}
-
-// --------------------------------------------------------------------------
-// Methods
-// --------------------------------------------------------------------------
-
-/**
- * Initializes the values drawing uniform random samples from the range
- * [{@value #PAR_MIN}, {@value #PAR_MAX}[.
- * @return always false
- */
-public boolean execute() {
-
- if(setter.isInteger())
- {
- long d = max.longValue() - min.longValue();
- for (int i = 0; i < Network.size(); ++i)
- {
- setter.set(i,CommonState.r.nextLong(d)+min.longValue());
- }
- }
- else
- {
- double d = max.doubleValue() - min.doubleValue();
- for (int i = 0; i < Network.size(); ++i)
- {
- setter.set(i,CommonState.r.nextDouble()*d+
- min.doubleValue());
- }
- }
-
- return false;
-}
-
-// --------------------------------------------------------------------------
-
-/**
- * Initializes the value drawing a uniform random sample from the range
- * [{@value #PAR_MIN}, {@value #PAR_MAX}[.
- * @param n the node to initialize
- */
-public void initialize(Node n) {
-
- if( setter.isInteger() )
- {
- long d = max.longValue() - min.longValue();
- setter.set(n,CommonState.r.nextLong(d) + min.longValue());
- }
- else
- {
- double d = max.doubleValue() - min.doubleValue();
- setter.set(n,CommonState.r.nextDouble()*d);
- }
-}
-
-// --------------------------------------------------------------------------
-
-}
+++ /dev/null
-/*
- * 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.vector;
-
-import java.io.*;
-
-import peersim.config.*;
-import peersim.core.*;
-import peersim.util.*;
-
-/**
- * Dump the content of a vector in a file. Each line
- * represent a single node.
- * Values are dumped to a file whose name is obtained from a
- * configurable prefix (set by {@value #PAR_BASENAME}), a number that is
- * increased before each dump by one, and the extension ".vec".
- * <p>
- * This observer class can observe any protocol field containing a
- * primitive value, provided that the field is associated with a getter method
- * that reads it.
- * @see VectControl
- * @see peersim.vector
- */
-public class ValueDumper extends VectControl {
-
-
-// --------------------------------------------------------------------------
-// Parameter names
-// --------------------------------------------------------------------------
-
-/**
- * This is the base name of the file where the values are saved. The full name
- * will be baseName+cycleid+".vec".
- * @config
- */
-private static final String PAR_BASENAME = "outf";
-
-// --------------------------------------------------------------------------
-// Fields
-// --------------------------------------------------------------------------
-
-/** Prefix name of this observer */
-private final String prefix;
-
-/** Base name of the file to be written */
-private final String baseName;
-
-private final FileNameGenerator fng;
-
-// --------------------------------------------------------------------------
-// Constructor
-// --------------------------------------------------------------------------
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param prefix the configuration prefix for this class
- */
-public ValueDumper(String prefix) {
-
- super(prefix);
- this.prefix = prefix;
- baseName = Configuration.getString(prefix + "." + PAR_BASENAME, null);
- if(baseName!=null) fng = new FileNameGenerator(baseName,".vec");
- else fng = null;
-}
-
-// --------------------------------------------------------------------------
-// Methods
-// --------------------------------------------------------------------------
-
-/**
- * Dump the content of a vector in a file. Each line
- * represent a single node.
- * Values are dumped to a file whose name is obtained from a
- * configurable prefix (set by {@value #PAR_BASENAME}), a number that is
- * increased before each dump by one, and the extension ".vec".
- * @return always false
- * @throws RuntimeException if there is an I/O problem
- */
-public boolean execute() {
-try
-{
- System.out.print(prefix + ": ");
-
- // initialize output streams
- if (baseName != null)
- {
- String filename = fng.nextCounterName();
- System.out.println("writing "+filename);
- PrintStream pstr =
- new PrintStream(new FileOutputStream(filename));
- for (int i = 0; i < Network.size(); ++i)
- {
- pstr.println(getter.get(i));
- }
- pstr.close();
- }
- else
- {
- System.out.println();
- for (int i = 0; i < Network.size(); ++i)
- {
- System.out.println(getter.get(i));
- }
- }
-}
-catch (IOException e)
-{
- throw new RuntimeException(prefix + ": Unable to write to file: " + e);
-}
-
- return false;
-}
-
-// ---------------------------------------------------------------------
-
-}
+++ /dev/null
-/*
- * 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.vector;
-
-import peersim.core.*;
-
-/**
- * Observes the cosine angle between two vectors. The number which is output is
- * the inner product divided by the product of the length of the vectors.
- * All values are converted to double before processing.
- * <p>
- * This observer class can observe any protocol field containing a
- * primitive value, provided that the field is associated with a getter method
- * that reads it.
- * The methods to be used are specified through parameter {@value #PAR_METHOD1}
- * and {@value #PAR_METHOD2}.
- * <p>
- * Please refer to package {@link peersim.vector} for a detailed description of
- * this mechanism.
- */
-public class VectAngle implements Control
-{
-
-// --------------------------------------------------------------------------
-// Parameters
-// --------------------------------------------------------------------------
-
-/**
- * The first protocol to be observed.
- * @config
- */
-private static final String PAR_PROT1 = "protocol1";
-
-/**
- * The second protocol to be observed.
- * @config
- */
-private static final String PAR_PROT2 = "protocol2";
-
-/**
- * The getter method used to obtain the values of the first protocol.
- * Defaults to <code>getValue</code> (for backward compatibility with previous
- * implementation of this class, that were based on the
- * {@link SingleValue} interface).
- * Refer to the {@linkplain peersim.vector vector package description} for more
- * information about getters and setters.
- * @config
- */
-private static final String PAR_METHOD1 = "getter1";
-
-/**
- * The getter method used to obtain the values of the second protocol.
- * Defaults to <code>getValue</code> (for backward compatibility with previous
- * implementation of this class, that were based on the
- * {@link SingleValue} interface).
- * Refer to the {@linkplain peersim.vector vector package description} for more
- * information about getters and setters.
- * @config
- */
-private static final String PAR_METHOD2 = "getter2";
-
-// --------------------------------------------------------------------------
-// Fields
-// --------------------------------------------------------------------------
-
-/** The prefix for this observer*/
-private final String name;
-
-private final Getter getter1;
-
-private final Getter getter2;
-
-// --------------------------------------------------------------------------
-// Initialization
-// --------------------------------------------------------------------------
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param prefix the configuration prefix for this class
- */
-public VectAngle(String prefix)
-{
- name = prefix;
- getter1 = new Getter(prefix,PAR_PROT1,PAR_METHOD1);
- getter2 = new Getter(prefix,PAR_PROT2,PAR_METHOD2);
-}
-
-// --------------------------------------------------------------------------
-// Methods
-// --------------------------------------------------------------------------
-
-/**
- * Observes the cosine angle between two vectors. The printed values
- * are: cosine, Eucledian norm of vect 1, Eucledian norm of vector 2,
- * angle in radians.
-* @return always false
-*/
-public boolean execute() {
-
- double sqrsum1 = 0, sqrsum2 = 0, prod = 0;
- for (int i = 0; i < Network.size(); ++i)
- {
- double v1= getter1.get(i).doubleValue();
- double v2= getter2.get(i).doubleValue();
- sqrsum1 += v1 * v1;
- sqrsum2 += v2 * v2;
- prod += v2 * v1;
- }
-
- double cos = prod / Math.sqrt(sqrsum1) / Math.sqrt(sqrsum2);
-
- // deal with numeric errors
- if( cos > 1 ) cos=1;
- if( cos < -1 ) cos = -1;
-
- System.out.println(name+": " + cos + " "
- + Math.sqrt(sqrsum1) + " " + Math.sqrt(sqrsum2) + " "
- + Math.acos(cos));
- return false;
-}
-
-//--------------------------------------------------------------------------
-
-}
+++ /dev/null
-/*
- * 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.vector;
-
-import peersim.core.*;
-
-/**
- * Serves as an abstract superclass for {@link Control}s that deal
- * with vectors.
- * It reads a {@link Setter} to be used by extending classes.
- */
-public abstract class VectControl implements Control {
-
-
-// --------------------------------------------------------------------------
-// Parameter names
-// --------------------------------------------------------------------------
-
-/**
- * The protocol to operate on.
- * @config
- */
-protected static final String PAR_PROT = "protocol";
-
-/**
- * The setter method used to set values in the protocol instances. Defaults to
- * <code>setValue</code>
- * (for backward compatibility with previous implementation of this
- * class, that were based on the {@link SingleValue} interface). Refer to the
- * {@linkplain peersim.vector vector package description} for more
- * information about getters and setters.
- * @config
- */
-protected static final String PAR_METHOD = "setter";
-
-/**
- * The getter method used to obtain the protocol values.
- * Defaults to <code>getValue</code>
- * (for backward compatibility with previous
- * implementation of this class, that were based on the
- * {@link SingleValue} interface).
- * Refer to the {@linkplain peersim.vector vector package description} for more
- * information about getters and setters.
- * @config
- */
-protected static final String PAR_GETTER = "getter";
-
-// --------------------------------------------------------------------------
-// Fields
-// --------------------------------------------------------------------------
-
-/** The setter to be used to write a vector. */
-protected final Setter setter;
-
-/** The getter to be used to read a vector. */
-protected final Getter getter;
-
-// --------------------------------------------------------------------------
-// Initialization
-// --------------------------------------------------------------------------
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param prefix the configuration prefix for this class
- */
-protected VectControl(String prefix)
-{
- setter = new Setter(prefix,PAR_PROT,PAR_METHOD);
- getter = new Getter(prefix,PAR_PROT,PAR_GETTER);
-}
-
-}
-
+++ /dev/null
-/*
- * 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.vector;
-
-import peersim.core.*;
-import peersim.dynamics.*;
-
-/**
- * Sets values in a protocol vector by copying the values of another
- * protocol vector.
- * The source is defined by {@value #PAR_SOURCE},
- * and getter method {@value peersim.vector.VectControl#PAR_GETTER}.
- * <p>
- * This dynamics class can copy any primitive field in the source
- * protocol to any primitive field in the destination protocol,
- * provided that the former field is associated with a getter method,
- * while the latter is associated with a setter method.
- * @see VectControl
- * @see peersim.vector
- */
-public class VectCopy extends VectControl implements NodeInitializer {
-
-
-//--------------------------------------------------------------------------
-//Parameters
-//--------------------------------------------------------------------------
-
-/**
- * The identifier of the protocol to be copied.
- * The vector values are copied from this vector.
- * @config
- */
-private static final String PAR_SOURCE = "source";
-
-
-// --------------------------------------------------------------------------
-// Variables
-// --------------------------------------------------------------------------
-
-/** Source getter */
-private final Getter source;
-
-//--------------------------------------------------------------------------
-//Initialization
-//--------------------------------------------------------------------------
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param prefix the configuration prefix for this class
- */
-public VectCopy(String prefix)
-{
- super(prefix);
- source = new Getter(prefix,PAR_SOURCE,PAR_GETTER);
-}
-
-//--------------------------------------------------------------------------
-//Method
-//--------------------------------------------------------------------------
-
-/**
- * Sets values in a protocol vector by copying the values of another
- * protocol vector. The source is defined by {@value #PAR_SOURCE},
- * and getter method {@value peersim.vector.VectControl#PAR_GETTER}.
- * @return always false
- */
-public boolean execute() {
-
- int size = Network.size();
- for (int i = 0; i < size; i++) {
- Number ret = source.get(i);
- if(setter.isInteger()) setter.set(i,ret.longValue());
- else setter.set(i,ret.doubleValue());
- }
-
- return false;
-}
-
-//--------------------------------------------------------------------------
-
-/**
- * Sets the value by copying the value of another
- * protocol. The source is defined by {@value #PAR_SOURCE},
- * and getter method {@value peersim.vector.VectControl#PAR_GETTER}.
- * @param n the node to initialize
- */
-public void initialize(Node n) {
-
- Number ret = source.get(n);
- if(setter.isInteger()) setter.set(n,ret.longValue());
- else setter.set(n,ret.doubleValue());
-}
-
-//--------------------------------------------------------------------------
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2006 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.vector;
-
-import java.lang.reflect.*;
-import java.util.*;
-
-import peersim.core.*;
-
-/**
- * This class provides a generic implementation of the
- * <code>java.lang.Comparator<code> interface specialized
- * for {@link Node} objects. Nodes are compared based
- * on one of their protocols, on which a configurable
- * method is invoked. Both the protocol id and the
- * method are specified in the constructor.
- * <br>
- * This comparator can be used, for example, to sort
- * an array of nodes based on method <code>getValue</code>
- * associated to the protocol <code>pid</code>:
- * <PRE>
- * Comparator c = new VectorComparator(pid, "getValue");
- * Array.sort(Node[] array, c);
- * </PRE>
- * Note that differently from other classes in this package,
- * VectorComparator is declared programmatically in the code
- * and not in the configuration file. It is included in this
- * package because it shares the same philosophy of the other
- * classes.
- *
- * @author Alberto Montresor
- * @version $Revision: 1.1 $
- */
-public class VectorComparator implements Comparator
-{
-
-//--------------------------------------------------------------------------
-//Fields
-//--------------------------------------------------------------------------
-
-/** Protocol identifier of the protocol to be observed */
-private final int pid;
-
-/** The getter to be used to obtain comparable values */
-private final Method method;
-
-//--------------------------------------------------------------------------
-//Initialization
-//--------------------------------------------------------------------------
-
-public VectorComparator(int pid, String methodName)
-{
- this.pid = pid;
- Node n = Network.prototype;
- if (n == null) {
- throw new IllegalStateException("No prototype node can be used to search methods");
- }
- Object p = n.getProtocol(pid);
- Class c = p.getClass();
- try {
- method = GetterSetterFinder.getGetterMethod(c, methodName);
- } catch (NoSuchMethodException e) {
- throw new IllegalArgumentException(e.getMessage());
- }
-}
-
-
-public int compare(Object o1, Object o2)
-{
- try {
- Comparable c1 = (Comparable) method.invoke(((Node) o1).getProtocol(pid));
- Comparable c2 = (Comparable) method.invoke(((Node) o2).getProtocol(pid));
- return c1.compareTo(c2);
- } catch (InvocationTargetException e) {
- throw new RuntimeException(e.getCause().getMessage());
- } catch (IllegalAccessException e) {
- throw new RuntimeException(e.getCause().getMessage());
- }
-}
-
-}
+++ /dev/null
-/*
- * 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.vector;
-
-import peersim.core.*;
-import peersim.util.*;
-
-/**
- * This class computes and reports statistics information about a vector.
- * Provided statistics include average, max, min, variance,
- * etc. Values are printed according to the string format of {@link
- * IncrementalStats#toString}.
- * @see VectControl
- * @see peersim.vector
- */
-public class VectorObserver extends VectControl {
-
-
-/** The name of this observer in the configuration */
-private final String prefix;
-
-
-//--------------------------------------------------------------------------
-//Initialization
-//--------------------------------------------------------------------------
-
-/**
- * Standard constructor that reads the configuration parameters.
- * Invoked by the simulation engine.
- * @param prefix the configuration prefix for this class
- */
-public VectorObserver(String prefix) {
-
- super(prefix);
- this.prefix = prefix;
-}
-
-//--------------------------------------------------------------------------
-// Methods
-//--------------------------------------------------------------------------
-
-/**
- * Prints statistics information about a vector.
- * Provided statistics include average, max, min, variance,
- * etc. Values are printed according to the string format of {@link
- * IncrementalStats#toString}.
- * @return always false
- */
-public boolean execute() {
-
- IncrementalStats stats = new IncrementalStats();
-
- for (int j = 0; j < Network.size(); j++)
- {
- Number v = getter.get(j);
- stats.add( v.doubleValue() );
- }
-
- System.out.println(prefix+": "+stats);
-
- return false;
-}
-
-}
+++ /dev/null
-package psgsim;
-
-import org.simgrid.msg.Host;
-import peersim.core.Network;
-import peersim.core.Node;
-
-import java.util.Comparator;
-import java.util.Map;
-import java.util.TreeMap;
-
-/**
- *
- * NodeHost class used to make the mapping Node-Host.
- *
- * @author Khaled Baati 26/10/2014
- * @version version 1.1
- */
-public class NodeHost {
-
- /**
- * A collection of map contained the couple (host,node)
- */
- public static TreeMap<Node, Host> mapHostNode = new TreeMap<Node, Host>(
- new Comparator<Node>() {
- public int compare(Node n1, Node n2) {
- return String.valueOf(n1.getID()).compareTo(
- String.valueOf(n2.getID()));
- }
- });
-
- /**
- * The main method to make the mapping Node to Host in the
- * {@link #mapHostNode} field
- */
- public static void start() {
- Host host = null;
- for (Integer i = 0; i < PSGSimulator.size; i++) {
- host = PSGPlatform.hostList[i];
- mapHostNode.put(Network.get(i), host);
- }
- }
-
- /**
- * This static method gets a Node instance associated with a host of your
- * platform.
- *
- * @param host
- * The host associated in your platform.
- * @return The node associated.
- */
- public static Node getNode(Host host) {
- for (Map.Entry<Node, Host> element : mapHostNode.entrySet()) {
- if (element.getValue() == host)
- return element.getKey();
- }
- return null;
- }
-
- /**
- * This static method gets a host instance associated with the node of your
- * platform.
- *
- * @param node
- * The node associated in your platform.
- * @return The host associated, else return null (host doesn't exist).
- */
- public static Host getHost(Node node) {
- for (Map.Entry<Node, Host> element : mapHostNode.entrySet()) {
- if (element.getKey() == node)
- return element.getValue();
- }
- return null;
- }
-}
+++ /dev/null
-package psgsim;
-
-import org.simgrid.msg.Host;
-import org.simgrid.msg.HostNotFoundException;
-
-import peersim.core.Node;
-
-/**
- *
- * This class can change the size of networks by adding and removing nodes, as
- * {@link peersim.dynamics.DynamicNetwork} in peersim.
- *
- * @author Khaled Baati 09/02/2015
- * @version version 1.1
- */
-public class PSGDynamicNetwork {
-
- /**
- * Removes the node from the network.
- *
- * @param node
- * the node to be removed
- */
- public static void remove(Node node) {
- // NodeHost.getHost(node).off();
- // Host h=NodeHost.mapHostNode.get(node);
- // NodeHost.mapHostNode.remove(node);
- PSGSimulator.size = PSGSimulator.size - 1;
- }
-
- /**
- * Adds a node to the network.
- *
- * @param node
- * the node to be added
- * @throws HostNotFoundException
- */
- public static void add(Node node) throws HostNotFoundException {
- Host host = PSGPlatform.hostList[(int) node.getID()];
- NodeHost.mapHostNode.put(node, host);
- if (PSGPlatform.interfED)
- new PSGProcessEvent(host, host.getName(), null).start();
- PSGSimulator.size = PSGSimulator.size + 1;
- }
-}
+++ /dev/null
-package psgsim;
-
-import java.io.*;
-import java.util.Comparator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.TreeMap;
-
-import org.jdom2.*;
-import org.jdom2.output.*;
-import org.simgrid.msg.Host;
-import org.simgrid.msg.Msg;
-
-import peersim.config.Configuration;
-import peersim.core.Control;
-import peersim.core.Protocol;
-
-/**
- * A class store different configuration information for simulation. It creates
- * the deployment file according to this informations.
- *
- * @author Khaled Baati 26/10/2014
- * @version version 1.1
- */
-
-public class PSGPlatform {
-
- enum timeUnit {
- us, ms, sec;
- }
-
- /** unit of measure. **/
- static int unit;
-
- /** the clock. **/
- static double time;
-
- /** the default unit of measure **/
- static final String sec = "sec";
-
- /** All protocols defined in the configuration file. **/
- static Protocol[] protocolsName;
-
- /** A numeric identifier associated for each protocol. **/
- static int[] pid;
-
- /** List of hos.t **/
- static Host[] hostList;
-
- /** A collection map represents the Control and its associated step. **/
- static Map<Control, Double> controlStepMap = new LinkedHashMap<Control, Double>();
-
- /** A collection map represents the protocol and its associated pid. **/
- static TreeMap<Protocol, Integer> protocolsPidsMap = new TreeMap<Protocol, Integer>(
- new Comparator<Protocol>() {
- public int compare(Protocol p1, Protocol p2) {
- return p1.toString().compareTo(p2.toString());
- }
- });
-
- /** A collection map represents all CDProtocol and its associated step **/
- static TreeMap<Protocol, Double> cdProtocolsStepMap = new TreeMap<Protocol, Double>(
- new Comparator<Protocol>() {
- public int compare(Protocol p1, Protocol p2) {
- return p1.toString().compareTo(p2.toString());
- }
- });
- /** the default platform file **/
- static final String platformFile = "platforms/psg.xml";
-
- /** the deployment file **/
- static final String deploymentFile = "deployment.xml";
-
- static Element racine;
- static Document document;
- static boolean interfED = false;
- static boolean interfCD = false;
-
- /** Prepare the deployment file **/
- static {
- DocType dtype = new DocType("platform",
- "http://simgrid.gforge.inria.fr/simgrid.dtd");
- racine = new Element("platform");
- document = new Document(racine, dtype);
- Attribute version = new Attribute("version", "3");
- racine.setAttribute(version);
- }
-
- // ========================== methods ==================================
- // =====================================================================
-
- /**
- * Convert PS unit time to Simgrid unit time
- *
- * @param valeur
- * the value to convert
- * @return time converted
- */
- public static double psToSgTime(long valeur) {
- timeUnit unit = unit();
- switch (unit) {
- case us:
- return ((double) valeur) / 1000000;
- case ms:
- return ((double) valeur) / 1000;
- default:
- return (double) valeur;
-
- }
- }
-
- /**
- * Convert Simgrid unit time to PS unit time
- *
- * @param valeur
- * the value to convert
- * @return time converted
- */
- public static long sgToPsTime(double valeur) {
- timeUnit unit = unit();
- switch (unit) {
- case us:
- return (long) valeur * 1000000;
- case ms:
- return (long) valeur * 1000;
- default:
- return (long) valeur;
-
- }
- }
-
- /**
- *
- * @return the duration of simulation.
- */
- public static long getDuration() {
- return Configuration.getLong("simulation.duration");
- }
-
- /**
- *
- * @return PeerSim Time
- */
- public static long getTime() {
- return sgToPsTime(Msg.getClock());
- }
-
- /**
- *
- * @return the Simgrid Clock
- */
- public static double getClock() {
- return Msg.getClock();
- }
-
- /**
- * Load and run initializers.
- */
- public static void init() {
- Object[] inits = Configuration.getInstanceArray("init");
- String names[] = Configuration.getNames("init");
- for (int i = 0; i < inits.length; ++i) {
- System.err.println("- Running initializer " + names[i] + ": "
- + inits[i].getClass().toString());
- ((Control) inits[i]).execute();
- }
- }
-
- /**
- * Load all controls and stores them in {@link #controlStepMap} collection
- * to be scheduled, and executed in {@link psgsim.PSGProcessController}.
- */
- public static void control() {
- // load controls
- String[] names = Configuration.getNames("control");
- Control control;
- for (int i = 0; i < names.length; ++i) {
- control = (Control) Configuration.getInstance(names[i]);
- Long stepControl = Configuration.getLong(names[i] + "." + "step");
- controlStepMap.put(control, psToSgTime(stepControl));
- }
- }
-
- /**
- * Lookup all protocols in the configuration file
- */
- public static void protocols() {
- String[] names = Configuration.getNames("protocol");
- Class[] interfaces;
- protocolsName = new Protocol[names.length];
- pid = new int[names.length];
- boolean save = false;
- for (int i = 0; i < names.length; i++) {
- protocolsName[i] = (Protocol) Configuration.getInstance(names[i]);
- if (i == names.length - 1)
- save = true;
- userProtocol(protocolsName[i], names[i], save);
- pid[i] = i;
- protocolsPidsMap.put(protocolsName[i], pid[i]);
- }
-
- }
-
- /**
- * Lookup CDProtocol and EDProtocol among all protocols
- *
- * @param prot
- * the protocol class
- * @param names
- * the protocol name
- * @param save
- * parameter equal true when parsing all protocols
- */
- public static void userProtocol(Protocol prot, String names, boolean save) {
- Class[] interfaces = prot.getClass().getInterfaces();
- for (int j = 0; j < interfaces.length; j++) {
- if (interfaces[j].getName().endsWith("EDProtocol")) {
- interfED = true;
- }
- if (interfaces[j].getName().endsWith("CDProtocol")) {
- String protName = names.substring("protocol".length() + 1);
- long step = Configuration.getLong("protocol" + "." + protName
- + "." + "step");
- cdProtocolsStepMap.put(prot, psToSgTime(step));
- }
- }
- if (save) {
- edProt();
- }
- }
-
- /**
- *
- */
- private static void edProt() {
- Host hostVal;
- hostList = Host.all();
- for (int i = 0; i < PSGSimulator.size; i++) {
- hostVal = hostList[i];
- Element process = new Element("process");
- racine.addContent(process);
- Attribute host = new Attribute("host", hostVal.getName());
- Attribute function = new Attribute("function",
- "psgsim.PSGProcessEvent");
- process.setAttribute(host);
- process.setAttribute(function);
- }
- save(deploymentFile);
-
- }
-
- /**
- *
- */
- @Deprecated
- private static void cdProt() {
- for (int i = 0; i < PSGSimulator.size; i++) {
- Element process = new Element("process");
- racine.addContent(process);
- Attribute host = new Attribute("host", String.valueOf(i));
- Attribute function = new Attribute("function",
- "psgsim.PSGProcessCycle");
- process.setAttribute(host);
- process.setAttribute(function);
-
- }
- save("deployment.xml");
-
- }
-
- /**
- * Reads given configuration property: "platform". If not found, returns the
- * default value.
- *
- * @return the platform file
- */
- public static String platformFile() {
- String defFile = platformFile;
- String file = Configuration.getString("platform", defFile);
- return file;
- }
-
- /**
- * Reads given configuration property: "unit". If not found, returns the
- * default value (ms).
- *
- * @return the unit of measure
- */
- public static timeUnit unit() {
- String defUnit = sec;
- String unit = Configuration.getString("unit", defUnit);
- timeUnit t = timeUnit.valueOf(unit);
- return t;
- }
-
- /**
- * Create the deployment file
- *
- * @param file
- * the name of the deployment file
- */
- public static void save(String file) {
- try {
- // On utilise ici un affichage classique avec getPrettyFormat()
- XMLOutputter out = new XMLOutputter(Format.getPrettyFormat());
- out.output(document, new FileOutputStream(file));
- } catch (java.io.IOException e) {
- }
- }
-
- /**
- * Delete the deployment file
- *
- * @param path
- * the path of the deployment file
- */
- public static void delete(String path) {
- File file = new File(path);
- try {
- file.delete();
- } catch (Exception e) {
- System.err.println("deployment file not found");
-
- }
- System.err.println(path + "file deleted");
-
- }
-
-}
+++ /dev/null
-package psgsim;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-import org.simgrid.msg.Host;
-import org.simgrid.msg.MsgException;
-
-import peersim.core.Control;
-
-/**
- * This class executes all controls object scheduled in the
- * {@link PSGPlatform#controlStepMap} collection.
- *
- * @author Khaled Baati 10/12/2014
- * @version version 1.1
- */
-public class PSGProcessController extends org.simgrid.msg.Process {
-
- private Map<Control, Double> controlStepMapTmp = new LinkedHashMap<Control, Double>();
-
- public PSGProcessController(Host host, String name, String[] args) {
- super(host, name, null);
- }
-
- @Override
- public void main(String[] args) throws MsgException {
- Double nextControlEvent;
- for (Map.Entry<Control, Double> entry : PSGPlatform.controlStepMap
- .entrySet()) {
- controlStepMapTmp.put(entry.getKey(), entry.getValue());
- }
- while (PSGPlatform.getTime() <= PSGPlatform.getDuration()) {
- for (Map.Entry<Control, Double> entrytmp : controlStepMapTmp
- .entrySet()) {
- Control cle = entrytmp.getKey();
- Double valeur = entrytmp.getValue();
- if (PSGPlatform.getTime() % valeur == 0) {
- cle.execute();
- if (PSGPlatform.getTime() != 0)
- for (Map.Entry<Control, Double> entry : PSGPlatform.controlStepMap
- .entrySet()) {
- if (cle == entry.getKey())
- controlStepMapTmp.replace(cle, valeur, valeur
- + entry.getValue());
-
- }
- }
- }
- nextControlEvent = next();
- if (nextControlEvent + PSGPlatform.getTime() >= PSGPlatform.getDuration()) {
- break;
- } else {
- waitFor(nextControlEvent);
- }
- }
- }
-
- private Double next() {
- Double min = controlStepMapTmp.values().iterator().next();
- for (Map.Entry<Control, Double> entry : controlStepMapTmp.entrySet()) {
- Double valeur = (entry.getValue() - PSGPlatform.getClock());
- if (min > valeur)
- min = valeur;
- }
-
- return min;
- }
-}
\ No newline at end of file
+++ /dev/null
-package psgsim;
-
-import java.util.Map.Entry;
-
-import org.simgrid.msg.Host;
-import peersim.cdsim.CDProtocol;
-import peersim.core.Node;
-import peersim.core.Protocol;
-
-/**
- * This class handle an event of type NextCycleEvent, received on the protocol
- * identified by a pid among all CDProtocols defined in the
- * {@link PSGPlatform#cdProtocolsStepMap} collection.
- * <p>
- * It executes the nextCyle method associated to this protocol.
- *
- * @author Khaled Baati 27/10/2014
- * @version version 1.1
- */
-public class PSGProcessCycle {
-
- /**
- * Executes the nextCycle method of the CDprotocol with the appropriate
- * parameters, and schedules the next call using {@link PSGSimulator#add}.
- *
- * @param host
- * the host on which this component is run
- * @param name
- * the host's name
- * @param delay
- * the start time
- * @param event
- * the actual event
- * @param pid
- * the protocol identifier
- */
- public static void nextCycle(Host host, String name, double delay,
- Object event, int pid) {
- CDProtocol cdp = null;
- Node node = NodeHost.getNode(host);
- cdp = (CDProtocol) node.getProtocol(pid);
- cdp.nextCycle(node, pid);
- PSGTransport.flush();
- for (Entry<Protocol, Double> entry : PSGPlatform.cdProtocolsStepMap
- .entrySet()) {
- Double step = entry.getValue();
- for (Entry<Protocol, Integer> p : PSGPlatform.protocolsPidsMap
- .entrySet()) {
- if (p.getValue() == pid) {
- break;
- }
- }
- if (PSGPlatform.getTime() <= PSGPlatform.getDuration() && host.isOn()) {
- PSGSimulator.add(PSGPlatform.sgToPsTime(step), event, node, pid);
- }
- }
- }
-
-}
+++ /dev/null
-package psgsim;
-
-import org.simgrid.msg.Host;
-import org.simgrid.msg.MsgException;
-
-import peersim.core.Node;
-import peersim.edsim.EDProtocol;
-
-/**
- * This class extends {@link org.simgrid.msg.Process} which creates a process
- * for each host (corresponding to node in peersim) in the system.
- * <p>
- * The main method of this class is to handle events received, by calling the
- * processEvent method on the corresponding node and pid.
- * <p>
- * See {@link peersim.edsim.EDProtocol#processEvent}
- *
- * @author Khaled Baati 28/10/2014
- * @version version 1.1
- */
-public class PSGProcessEvent extends org.simgrid.msg.Process {
- /** The delivered event **/
- private PSGTask task;
- /** The current protocol **/
- private EDProtocol prot;
- /** The identifier of the current protocol **/
- private int pid;
-
- /**
- * Constructs a new process from the name of a host.
- *
- * @param host
- * the local host to create according to the active node in
- * peersim
- * @param name
- * the host's name
- * @param args
- * The arguments of main method of the process.
- */
- public PSGProcessEvent(Host host, String name, String[] args) {
- super(host, name, args);
- }
-
- @Override
- public void main(String[] args) throws MsgException {
- Node node = NodeHost.getNode(getHost());
- Host.setAsyncMailbox(getHost().getName());
- while (PSGPlatform.getTime() < PSGPlatform.getDuration()) {
- task = null;
- task = (PSGTask) PSGTask.receive(Host.currentHost().getName(),
- PSGPlatform.psToSgTime(PSGPlatform.getDuration() - PSGPlatform.getTime()-1));
- if (task != null && PSGPlatform.getTime() < PSGPlatform.getDuration()) {
- pid = task.getPid();
- prot = (EDProtocol) node.getProtocol(pid);
- prot.processEvent(node, pid, task.getEvent());
- PSGTransport.flush();
- } else
- break;
- }
- }
-
-}
+++ /dev/null
-package psgsim;
-
-import org.simgrid.msg.Host;
-import org.simgrid.msg.MsgException;
-
-import peersim.core.Node;
-import peersim.edsim.EDProtocol;
-import peersim.edsim.NextCycleEvent;
-
-/**
- * This class extends {@link org.simgrid.msg.Process}, it creates a process for
- * each event added in {@link PSGSimulator#add}.
- * <p>
- * This class performs to launch the appropriate call according to the type of
- * the event;
- * <p>
- * - A NextCycleEvent: the event will be delivered to the
- * {@link PSGProcessCycle} for treatment.
- * <p>
- * - Otherwise the event is delivered to the destination protocol, that must
- * implement {@link EDProtocol}, and the processEvent method is executed.
- *
- * @author Khaled Baati 12/11/2014
- * @version version 1.1
- */
-public class PSGProcessLauncher extends org.simgrid.msg.Process {
- private EDProtocol prot = null;
- private int pid;
- private double delay;
- private Object event;
- private Host host;
-
- /**
- * Constructs a new process from the name of a host and with the associated
- * parameters
- *
- * @param host
- * the local host
- * @param name
- * the host's name
- * @param delay
- * the start time of the process
- * @param event
- * the event added to the simulator
- * @param pid
- * the protocol identifier
- */
- public PSGProcessLauncher(Host host, String name, double delay, Object event,
- int pid) {
- super(host, name, null, delay, -1);
- this.host = host;
- this.pid = pid;
- this.event = event;
- this.delay = delay;
- }
-
- public PSGProcessLauncher(Host host, String name, String[] args) {
-
- }
-
- @Override
- public void main(String[] args) throws MsgException {
- Node node = NodeHost.getNode(host);
- if (event instanceof NextCycleEvent) {
- PSGProcessCycle.nextCycle(Host.currentHost(), host.getName(),
- delay, event, pid);
- } else {
- prot = (EDProtocol) node.getProtocol(pid);
- prot.processEvent(node, pid, event);
- PSGTransport.flush();
- }
- waitFor(500);
- }
-}
\ No newline at end of file
+++ /dev/null
-package psgsim;
-
-import org.simgrid.msg.Host;
-import org.simgrid.msg.HostNotFoundException;
-import org.simgrid.msg.Msg;
-import org.simgrid.msg.NativeException;
-
-import peersim.core.CommonState;
-import peersim.core.Network;
-import peersim.core.Node;
-
-/**
- * This is the main entry point to Simgrid simulator. This class loads the
- * different parameters and initializes the simulation.
- *
- * @author Khaled Baati 14/10/2014
- * @version version 1.1
- */
-public class PSGSimulator {
- public static int size;
-
- static {
- Network.reset();
- size = Network.size();
- }
-
- // ========================== methods ==================================
- // =====================================================================
-
- /**
- * Adds a new event to be scheduled, specifying the number of time units of
- * delay (in seconds), the node and the protocol identifier to which the
- * event will be delivered. A {@link psgsim.PSGProcessLauncher} process will
- * be created according to this event.
- *
- * @param delay
- * The number of time units (seconds in simgrid) before the event
- * is scheduled.
- * @param event
- * The object associated to this event
- * @param src
- * The node associated to the event.
- * @param pid
- * The identifier of the protocol to which the event will be
- * delivered
- */
- public static void add(long delay, Object event, Node src, int pid) {
- Host host = NodeHost.getHost(src);
- double startTime = PSGPlatform.psToSgTime(delay) + Msg.getClock();
- if (startTime < PSGPlatform.psToSgTime(PSGPlatform.getDuration()) ) {
- try {
- /**
- * random instruction associated to Heap.add(...) method in
- * peersim.edsim
- **/
- CommonState.r.nextInt(1 << 8);
- new PSGProcessLauncher(host, host.getName(), startTime, event,
- pid).start();
- } catch (HostNotFoundException e) {
- System.err.println("Host not found");
- }
- }
-
- }
-
- // ========================== main method ==================================
- // =====================================================================
- public static void main() throws NativeException, HostNotFoundException {
-
- String platformfile = PSGPlatform.platformFile();
- System.err.println(platformfile + " loaded");
- String[] arguments = { platformfile, "deployment.xml" };
- Msg.init(arguments);
-
- /** construct the platform */
- Msg.createEnvironment(arguments[0]);
-
- PSGPlatform.protocols();
-
- /** deploy the application **/
- Msg.deployApplication(arguments[1]);
-
- /** construct the host-node mapping **/
- NodeHost.start();
-
- /** Process Controller **/
- PSGPlatform.control();
- if (!PSGPlatform.controlStepMap.isEmpty())
- new PSGProcessController(PSGPlatform.hostList[0],
- PSGPlatform.hostList[0].getName(), null).start();
-
- /** Load and execute the initializers classes in the configuration file **/
- PSGPlatform.init();
-
- PSGPlatform.delete("deployment.xml");
- /** execute the simulation. **/
- Msg.run();
- }
-}
+++ /dev/null
-package psgsim;
-
-import org.simgrid.msg.HostFailureException;
-import org.simgrid.msg.Task;
-import org.simgrid.msg.TimeoutException;
-import org.simgrid.msg.TransferFailureException;
-
-/**
- * The PSGTask includes all the parameters of sending a message as the size, the
- * compute duration and the protocol identifier.
- *
- * @author Khaled Baati 28/10/2014
- * @version version 1.1
- */
-public class PSGTask extends org.simgrid.msg.Task {
- /** The Message to be sent **/
- private Object event;
- /** The protocol identifier **/
- private int pid;
-
- /**
- * Construct a new task to be sent.
- *
- * @param name
- * The name of task
- * @param computeDuration
- * The compute duration
- *
- * @param messageSize
- * The size of the message
- * @param event
- * The message to be sent
- * @param pid
- * The protocol identifier
- */
- public PSGTask(String name, double computeDuration, double messageSize,
- Object event, int pid) {
- super(name, computeDuration, messageSize);
- this.event = event;
- this.pid = pid;
- }
-
- /**
- *
- * @return the protocol identifier
- */
- public int getPid() {
- return pid;
- }
-
- /**
- *
- * @return the message
- */
- public Object getEvent() {
- return event;
- }
-
- /**
- * Retrieves next task on the mailbox identified by the specified name (wait
- * at most timeout seconds)
- *
- * @param mailbox
- * the mailbox on where to receive the task
- * @param timeout
- * the timeout to wait for receiving the task
- * @return the task
- */
- public static Task receive(String mailbox, double timeout) {
- double time = PSGPlatform.getClock();
- if (time + timeout > PSGPlatform.getClock()) {
- try {
- return receive(mailbox, timeout, null);
- } catch (TimeoutException e) {
- } catch (TransferFailureException e) {
- e.printStackTrace();
- } catch (HostFailureException e) {
- e.printStackTrace();
- }
- }
- return null;
-
- }
-
-}
+++ /dev/null
-package psgsim;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-import peersim.config.Configuration;
-import peersim.config.IllegalParameterException;
-import peersim.core.CommonState;
-import peersim.core.Node;
-import peersim.transport.Transport;
-
-/**
- * PSGTransport is the transport layer. it is responsible for sending messages.
- *
- * @author Khaled Baati 28/10/2014
- * @version 1.1
- */
-public class PSGTransport implements Transport {
-
- private static double computeDuration = 0;
- private PSGTask task;
- private static Map<PSGTask, String> taskToSend = new LinkedHashMap<PSGTask, String>();
-
- /**
- * String name of the parameter used to configure the minimum latency. * @config
- */
- private static final String PAR_MINDELAY = "mindelay";
-
- /**
- * String name of the parameter used to configure the maximum latency.
- * Defaults to {@value #PAR_MINDELAY}, which results in a constant delay.
- *
- * @config
- */
- private static final String PAR_MAXDELAY = "maxdelay";
-
- /** Minimum delay for message sending */
- private long min;
- /** Maximum delay for message sending */
- private long max;
-
- /**
- * Difference between the max and min delay plus one. That is, max delay is
- * min+range-1.
- */
- private long range;
-
- public PSGTransport() {
-
- }
-
- public PSGTransport(String prefix) {
- min = Configuration.getLong(prefix + "." + PAR_MINDELAY);
- max = Configuration.getLong(prefix + "." + PAR_MAXDELAY, min);
- if (max < min)
- throw new IllegalParameterException(prefix + "." + PAR_MAXDELAY,
- "The maximum latency cannot be smaller than the minimum latency");
- range = max - min + 1;
- }
-
- /**
- * Returns <code>this</code>. This way only one instance exists in the
- * system that is linked from all the nodes. This is because this protocol
- * has no node specific state.
- */
- public Object clone() {
- return this;
- }
-
- @Override
- public void send(Node src, Node dest, Object msg, int pid) {
- double commSizeLat = 0;
- /**
- * random instruction associated to UniformRandomTransport.send(...)
- * method in peersim.transport
- **/
- long delay = (range == 1 ? min : min + CommonState.r.nextLong(range));
- CommonState.r.nextInt(1 << 8);
- if (msg instanceof Sizable) {
- commSizeLat = ((Sizable) msg).getSize();
- }
-
- task = new PSGTask("task sender_" + src.getID(), computeDuration,
- commSizeLat, msg, pid);
- taskToSend.put(this.task, NodeHost.getHost(dest).getName());
-
- }
-
- /**
- * Process for sending all messages in the queue.
- */
- public static void flush() {
- Map<PSGTask, String> taskToSendCopy = new LinkedHashMap<PSGTask, String>();
- for (Map.Entry<PSGTask, String> entry : taskToSend.entrySet()) {
- taskToSendCopy.put(entry.getKey(), entry.getValue());
- }
- taskToSend.clear();
- for (Map.Entry<PSGTask, String> entry : taskToSendCopy.entrySet()) {
- PSGTask task = entry.getKey();
- String dest = entry.getValue();
- task.dsend(dest);
- }
- taskToSendCopy.clear();
-
- }
-
- @Override
- public long getLatency(Node src, Node dest) {
- /**
- * random instruction associated to
- * UniformRandomTransport.getLatency(...) method in peersim.transport
- **/
- return (range == 1 ? min : min + CommonState.r.nextLong(range));
- }
-}
+++ /dev/null
-package psgsim;
-
-/**
- * An interface which defines a size for the message or the event to be sent. If you
- * wish that your message has a size, your class message must implements this
- * interface and defines a size parameter in the constructor.
- *
- * @author Khaled Baati 05/02/2015
- * @version 1.1
- *
- */
-public interface Sizable {
- /**
- *
- * @return The size of the message
- */
- public double getSize();
-}
+++ /dev/null
-#!/bin/bash
-
-if [ $(uname -m) = "i686" ]; then
- eval ulimit -s 64
-else
- eval ulimit -s 128
-fi
-
-echo -e "\n";
-echo '------------- Execute the edaggregation example under PSG -------------';
-echo -e "\n";
-java -Xmx1024m -cp lib.jar:classes:../../simgrid.jar peersim.Simulator configs/edaggregationPSG.txt
-echo -e "\n";
-echo '------------- Execute the edaggregation example under PS -------------';
-echo -e "\n";
-java -Xmx1024m -cp lib.jar:classes:../../simgrid.jar peersim.Simulator configs/edaggregation.txt
-echo -e "\n";
-echo '------------- Execute the chord example under PSG -------------';
-echo -e "\n";
-java -Xmx1024m -cp lib.jar:classes:../../simgrid.jar peersim.Simulator configs/chordPSG.txt
-echo -e "\n";
-echo '------------- Execute the chord example under PS -------------';
-echo -e "\n";
-java -Xmx1024m -cp lib.jar:classes:../../simgrid.jar peersim.Simulator configs/chord.txt
-echo -e "\n";
-echo '------------- Compare the 2 results PS and PSG -------------';
-echo -e "\n";
-
-cd outputs
-
-ListeRep="$(find * -type d -prune)" # liste des repertoires
-for Rep in ${ListeRep}; do
- cd $Rep
- VAR=$(diff ps.txt psg.txt)
- if [ "${VAR}"1 = 1 ]
- then
- echo The results of diff "for" the $Rep example is '.............:)';
- else
- echo The results of diff "for" the $Rep example is '.............:(';
- fi
- cd ..
-done
-echo -e "\n";
-exit 0
-