Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
peersimgrid release 1.0
authorkbaati <kbaati@realopt-Latitude-E6530>
Fri, 24 Jul 2015 10:24:03 +0000 (12:24 +0200)
committerkbaati <kbaati@realopt-Latitude-E6530>
Fri, 24 Jul 2015 10:24:03 +0000 (12:24 +0200)
190 files changed:
contrib/psg/README.txt [new file with mode: 0644]
contrib/psg/configs/bittorrent.txt [new file with mode: 0644]
contrib/psg/configs/bittorrentPSG.txt [new file with mode: 0644]
contrib/psg/configs/chord.txt [new file with mode: 0644]
contrib/psg/configs/chordPSG.txt [new file with mode: 0644]
contrib/psg/configs/edaggregation.txt [new file with mode: 0644]
contrib/psg/configs/edaggregationPSG.txt [new file with mode: 0644]
contrib/psg/configs/symphony.txt [new file with mode: 0644]
contrib/psg/configs/symphonyPSG.txt [new file with mode: 0644]
contrib/psg/lib.jar [new file with mode: 0644]
contrib/psg/platforms/psg.xml [new file with mode: 0644]
contrib/psg/run.sh [new file with mode: 0755]
contrib/psg/src/example/bittorrent/BTObserver.java [new file with mode: 0644]
contrib/psg/src/example/bittorrent/BitTorrent.java [new file with mode: 0644]
contrib/psg/src/example/bittorrent/BitfieldMsg.java [new file with mode: 0644]
contrib/psg/src/example/bittorrent/IntMsg.java [new file with mode: 0644]
contrib/psg/src/example/bittorrent/NetworkDynamics.java [new file with mode: 0644]
contrib/psg/src/example/bittorrent/NetworkInitializer.java [new file with mode: 0644]
contrib/psg/src/example/bittorrent/NodeInitializer.java [new file with mode: 0644]
contrib/psg/src/example/bittorrent/PeerSetMsg.java [new file with mode: 0644]
contrib/psg/src/example/bittorrent/SimpleEvent.java [new file with mode: 0644]
contrib/psg/src/example/bittorrent/SimpleMsg.java [new file with mode: 0644]
contrib/psg/src/example/chord/ChordInitializer.java [new file with mode: 0644]
contrib/psg/src/example/chord/ChordMessage.java [new file with mode: 0644]
contrib/psg/src/example/chord/ChordProtocol.java [new file with mode: 0644]
contrib/psg/src/example/chord/CreateNw.java [new file with mode: 0644]
contrib/psg/src/example/chord/FinalMessage.java [new file with mode: 0644]
contrib/psg/src/example/chord/LookUpMessage.java [new file with mode: 0644]
contrib/psg/src/example/chord/MessageCounterObserver.java [new file with mode: 0644]
contrib/psg/src/example/chord/NodeComparator.java [new file with mode: 0644]
contrib/psg/src/example/chord/Parameters.java [new file with mode: 0644]
contrib/psg/src/example/chord/TrafficGenerator.java [new file with mode: 0644]
contrib/psg/src/example/edaggregation/AverageED.java [new file with mode: 0644]
contrib/psg/src/example/symphony/AdapterIterableNetwork.java [new file with mode: 0644]
contrib/psg/src/example/symphony/AdapterSymphonyNodeComparator.java [new file with mode: 0644]
contrib/psg/src/example/symphony/Handler.java [new file with mode: 0644]
contrib/psg/src/example/symphony/LeaveTest.java [new file with mode: 0644]
contrib/psg/src/example/symphony/Message.java [new file with mode: 0644]
contrib/psg/src/example/symphony/NetworkSizeEstimatorProtocolInterface.java [new file with mode: 0644]
contrib/psg/src/example/symphony/RandomRouteTest.java [new file with mode: 0644]
contrib/psg/src/example/symphony/RingRouteTest.java [new file with mode: 0644]
contrib/psg/src/example/symphony/RoutingException.java [new file with mode: 0644]
contrib/psg/src/example/symphony/SimpleNetworkSizeEstimatorProtocol.java [new file with mode: 0644]
contrib/psg/src/example/symphony/SymphonyEstimationProtocol.java [new file with mode: 0644]
contrib/psg/src/example/symphony/SymphonyNetworkBuilder.java [new file with mode: 0644]
contrib/psg/src/example/symphony/SymphonyNetworkChecker.java [new file with mode: 0644]
contrib/psg/src/example/symphony/SymphonyNetworkManager.java [new file with mode: 0644]
contrib/psg/src/example/symphony/SymphonyNodeComparator.java [new file with mode: 0644]
contrib/psg/src/example/symphony/SymphonyNodeInizializer.java [new file with mode: 0644]
contrib/psg/src/example/symphony/SymphonyProtocol.java [new file with mode: 0644]
contrib/psg/src/example/symphony/SymphonyStatistics.java [new file with mode: 0644]
contrib/psg/src/example/symphony/Tuple.java [new file with mode: 0644]
contrib/psg/src/example/symphony/test/NetworkEstimationTest.java [new file with mode: 0644]
contrib/psg/src/peersim/Simulator.java [new file with mode: 0644]
contrib/psg/src/peersim/cdsim/CDProtocol.java [new file with mode: 0644]
contrib/psg/src/peersim/cdsim/CDSimulator.java [new file with mode: 0644]
contrib/psg/src/peersim/cdsim/CDState.java [new file with mode: 0644]
contrib/psg/src/peersim/cdsim/DaemonProtocol.java [new file with mode: 0644]
contrib/psg/src/peersim/cdsim/FullNextCycle.java [new file with mode: 0644]
contrib/psg/src/peersim/cdsim/NextCycle.java [new file with mode: 0644]
contrib/psg/src/peersim/cdsim/Shuffle.java [new file with mode: 0644]
contrib/psg/src/peersim/config/CheckConfig.java [new file with mode: 0644]
contrib/psg/src/peersim/config/ClassFinder.java [new file with mode: 0644]
contrib/psg/src/peersim/config/ConfigContainer.java [new file with mode: 0644]
contrib/psg/src/peersim/config/ConfigProperties.java [new file with mode: 0644]
contrib/psg/src/peersim/config/Configuration.java [new file with mode: 0644]
contrib/psg/src/peersim/config/FastConfig.java [new file with mode: 0644]
contrib/psg/src/peersim/config/IllegalParameterException.java [new file with mode: 0644]
contrib/psg/src/peersim/config/MissingParameterException.java [new file with mode: 0644]
contrib/psg/src/peersim/config/NullPrintStream.java [new file with mode: 0644]
contrib/psg/src/peersim/config/Operators.java [new file with mode: 0644]
contrib/psg/src/peersim/config/ParsedProperties.java [new file with mode: 0644]
contrib/psg/src/peersim/core/Cleanable.java [new file with mode: 0644]
contrib/psg/src/peersim/core/CommonState.java [new file with mode: 0644]
contrib/psg/src/peersim/core/Control.java [new file with mode: 0644]
contrib/psg/src/peersim/core/Fallible.java [new file with mode: 0644]
contrib/psg/src/peersim/core/GeneralNode.java [new file with mode: 0644]
contrib/psg/src/peersim/core/IdleProtocol.java [new file with mode: 0644]
contrib/psg/src/peersim/core/Linkable.java [new file with mode: 0644]
contrib/psg/src/peersim/core/MaliciousProtocol.java [new file with mode: 0644]
contrib/psg/src/peersim/core/ModifiableNode.java [new file with mode: 0644]
contrib/psg/src/peersim/core/Network.java [new file with mode: 0644]
contrib/psg/src/peersim/core/Node.java [new file with mode: 0644]
contrib/psg/src/peersim/core/OracleIdleProtocol.java [new file with mode: 0644]
contrib/psg/src/peersim/core/OverlayGraph.java [new file with mode: 0644]
contrib/psg/src/peersim/core/Protocol.java [new file with mode: 0644]
contrib/psg/src/peersim/core/Scheduler.java [new file with mode: 0644]
contrib/psg/src/peersim/dynamics/DynamicNetwork.java [new file with mode: 0644]
contrib/psg/src/peersim/dynamics/MethodInvoker.java [new file with mode: 0644]
contrib/psg/src/peersim/dynamics/NodeInitializer.java [new file with mode: 0644]
contrib/psg/src/peersim/dynamics/OscillatingNetwork.java [new file with mode: 0644]
contrib/psg/src/peersim/dynamics/RandNI.java [new file with mode: 0644]
contrib/psg/src/peersim/dynamics/StarNI.java [new file with mode: 0644]
contrib/psg/src/peersim/dynamics/WireByMethod.java [new file with mode: 0644]
contrib/psg/src/peersim/dynamics/WireFromFile.java [new file with mode: 0644]
contrib/psg/src/peersim/dynamics/WireGraph.java [new file with mode: 0644]
contrib/psg/src/peersim/dynamics/WireKOut.java [new file with mode: 0644]
contrib/psg/src/peersim/dynamics/WireRegRootedTree.java [new file with mode: 0644]
contrib/psg/src/peersim/dynamics/WireRingLattice.java [new file with mode: 0644]
contrib/psg/src/peersim/dynamics/WireScaleFreeBA.java [new file with mode: 0644]
contrib/psg/src/peersim/dynamics/WireScaleFreeDM.java [new file with mode: 0644]
contrib/psg/src/peersim/dynamics/WireStar.java [new file with mode: 0644]
contrib/psg/src/peersim/dynamics/WireWS.java [new file with mode: 0644]
contrib/psg/src/peersim/edsim/CDScheduler.java [new file with mode: 0644]
contrib/psg/src/peersim/edsim/ControlEvent.java [new file with mode: 0644]
contrib/psg/src/peersim/edsim/EDProtocol.java [new file with mode: 0644]
contrib/psg/src/peersim/edsim/EDSimulator.java [new file with mode: 0644]
contrib/psg/src/peersim/edsim/Heap.java [new file with mode: 0644]
contrib/psg/src/peersim/edsim/NextCycleEvent.java [new file with mode: 0644]
contrib/psg/src/peersim/edsim/PriorityQ.java [new file with mode: 0644]
contrib/psg/src/peersim/edsim/RandNextCycle.java [new file with mode: 0644]
contrib/psg/src/peersim/edsim/RegRandNextCycle.java [new file with mode: 0644]
contrib/psg/src/peersim/edsim/edsim_jsp.xmi [new file with mode: 0644]
contrib/psg/src/peersim/edsim/edsim_kdm.xmi [new file with mode: 0644]
contrib/psg/src/peersim/graph/BitMatrixGraph.java [new file with mode: 0644]
contrib/psg/src/peersim/graph/ConstUndirGraph.java [new file with mode: 0644]
contrib/psg/src/peersim/graph/FastUndirGraph.java [new file with mode: 0644]
contrib/psg/src/peersim/graph/Graph.java [new file with mode: 0644]
contrib/psg/src/peersim/graph/GraphAlgorithms.java [new file with mode: 0644]
contrib/psg/src/peersim/graph/GraphFactory.java [new file with mode: 0644]
contrib/psg/src/peersim/graph/GraphIO.java [new file with mode: 0644]
contrib/psg/src/peersim/graph/NeighbourListGraph.java [new file with mode: 0644]
contrib/psg/src/peersim/graph/PrefixSubGraph.java [new file with mode: 0644]
contrib/psg/src/peersim/graph/SubGraphEdges.java [new file with mode: 0644]
contrib/psg/src/peersim/graph/UndirectedGraph.java [new file with mode: 0644]
contrib/psg/src/peersim/rangesim/ProcessHandler.java [new file with mode: 0644]
contrib/psg/src/peersim/rangesim/ProcessManager.java [new file with mode: 0644]
contrib/psg/src/peersim/rangesim/RangeSimulator.java [new file with mode: 0644]
contrib/psg/src/peersim/rangesim/TaggedOutputStream.java [new file with mode: 0644]
contrib/psg/src/peersim/reports/BallExpansion.java [new file with mode: 0644]
contrib/psg/src/peersim/reports/Clustering.java [new file with mode: 0644]
contrib/psg/src/peersim/reports/ConnectivityObserver.java [new file with mode: 0644]
contrib/psg/src/peersim/reports/DegreeStats.java [new file with mode: 0644]
contrib/psg/src/peersim/reports/GraphObserver.java [new file with mode: 0644]
contrib/psg/src/peersim/reports/GraphPrinter.java [new file with mode: 0644]
contrib/psg/src/peersim/reports/GraphStats.java [new file with mode: 0644]
contrib/psg/src/peersim/reports/MemoryObserver.java [new file with mode: 0644]
contrib/psg/src/peersim/reports/RandRemoval.java [new file with mode: 0644]
contrib/psg/src/peersim/transport/E2ENetwork.java [new file with mode: 0644]
contrib/psg/src/peersim/transport/E2ETransport.java [new file with mode: 0644]
contrib/psg/src/peersim/transport/KingParser.java [new file with mode: 0644]
contrib/psg/src/peersim/transport/RouterInfo.java [new file with mode: 0644]
contrib/psg/src/peersim/transport/Transport.java [new file with mode: 0644]
contrib/psg/src/peersim/transport/TriangularMatrixParser.java [new file with mode: 0644]
contrib/psg/src/peersim/transport/UniformRandomTransport.java [new file with mode: 0644]
contrib/psg/src/peersim/transport/UniformRouterAssignment.java [new file with mode: 0644]
contrib/psg/src/peersim/transport/UnreliableTransport.java [new file with mode: 0644]
contrib/psg/src/peersim/util/ExtendedRandom.java [new file with mode: 0644]
contrib/psg/src/peersim/util/FileNameGenerator.java [new file with mode: 0644]
contrib/psg/src/peersim/util/IncrementalFreq.java [new file with mode: 0644]
contrib/psg/src/peersim/util/IncrementalStats.java [new file with mode: 0644]
contrib/psg/src/peersim/util/IndexIterator.java [new file with mode: 0644]
contrib/psg/src/peersim/util/LinearIterator.java [new file with mode: 0644]
contrib/psg/src/peersim/util/MedianStats.java [new file with mode: 0644]
contrib/psg/src/peersim/util/MomentStats.java [new file with mode: 0644]
contrib/psg/src/peersim/util/RandPermutation.java [new file with mode: 0644]
contrib/psg/src/peersim/util/StringListParser.java [new file with mode: 0644]
contrib/psg/src/peersim/util/WeightedRandPerm.java [new file with mode: 0644]
contrib/psg/src/peersim/vector/Getter.java [new file with mode: 0644]
contrib/psg/src/peersim/vector/GetterSetterFinder.java [new file with mode: 0644]
contrib/psg/src/peersim/vector/InitVectFromFile.java [new file with mode: 0644]
contrib/psg/src/peersim/vector/LinearDistribution.java [new file with mode: 0644]
contrib/psg/src/peersim/vector/Normalizer.java [new file with mode: 0644]
contrib/psg/src/peersim/vector/PeakDistribution.java [new file with mode: 0644]
contrib/psg/src/peersim/vector/Setter.java [new file with mode: 0644]
contrib/psg/src/peersim/vector/SingleValue.java [new file with mode: 0644]
contrib/psg/src/peersim/vector/SingleValueComparator.java [new file with mode: 0644]
contrib/psg/src/peersim/vector/SingleValueHolder.java [new file with mode: 0644]
contrib/psg/src/peersim/vector/SingleValueObserver.java [new file with mode: 0644]
contrib/psg/src/peersim/vector/TestVectors.java [new file with mode: 0644]
contrib/psg/src/peersim/vector/UniformDistribution.java [new file with mode: 0644]
contrib/psg/src/peersim/vector/ValueDumper.java [new file with mode: 0644]
contrib/psg/src/peersim/vector/VectAngle.java [new file with mode: 0644]
contrib/psg/src/peersim/vector/VectControl.java [new file with mode: 0644]
contrib/psg/src/peersim/vector/VectCopy.java [new file with mode: 0644]
contrib/psg/src/peersim/vector/VectorComparator.java [new file with mode: 0644]
contrib/psg/src/peersim/vector/VectorObserver.java [new file with mode: 0644]
contrib/psg/src/psgsim/NodeHost.java [new file with mode: 0644]
contrib/psg/src/psgsim/PSGDynamicNetwork.java [new file with mode: 0644]
contrib/psg/src/psgsim/PSGPlatform.java [new file with mode: 0644]
contrib/psg/src/psgsim/PSGProcessController.java [new file with mode: 0644]
contrib/psg/src/psgsim/PSGProcessCycle.java [new file with mode: 0644]
contrib/psg/src/psgsim/PSGProcessEvent.java [new file with mode: 0644]
contrib/psg/src/psgsim/PSGProcessLauncher.java [new file with mode: 0644]
contrib/psg/src/psgsim/PSGSimulator.java [new file with mode: 0644]
contrib/psg/src/psgsim/PSGTask.java [new file with mode: 0644]
contrib/psg/src/psgsim/PSGTransport.java [new file with mode: 0644]
contrib/psg/src/psgsim/Sizable.java [new file with mode: 0644]
contrib/psg/test.sh [new file with mode: 0755]
contrib/psg/tutorial.pdf [new file with mode: 0644]

diff --git a/contrib/psg/README.txt b/contrib/psg/README.txt
new file mode 100644 (file)
index 0000000..4435990
--- /dev/null
@@ -0,0 +1,48 @@
+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
diff --git a/contrib/psg/configs/bittorrent.txt b/contrib/psg/configs/bittorrent.txt
new file mode 100644 (file)
index 0000000..356b302
--- /dev/null
@@ -0,0 +1,46 @@
+#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
diff --git a/contrib/psg/configs/bittorrentPSG.txt b/contrib/psg/configs/bittorrentPSG.txt
new file mode 100644 (file)
index 0000000..647ccb4
--- /dev/null
@@ -0,0 +1,48 @@
+#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
diff --git a/contrib/psg/configs/chord.txt b/contrib/psg/configs/chord.txt
new file mode 100644 (file)
index 0000000..deeee8f
--- /dev/null
@@ -0,0 +1,51 @@
+# 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
diff --git a/contrib/psg/configs/chordPSG.txt b/contrib/psg/configs/chordPSG.txt
new file mode 100644 (file)
index 0000000..7e67047
--- /dev/null
@@ -0,0 +1,54 @@
+# 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
diff --git a/contrib/psg/configs/edaggregation.txt b/contrib/psg/configs/edaggregation.txt
new file mode 100644 (file)
index 0000000..d3aec12
--- /dev/null
@@ -0,0 +1,57 @@
+# 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
diff --git a/contrib/psg/configs/edaggregationPSG.txt b/contrib/psg/configs/edaggregationPSG.txt
new file mode 100644 (file)
index 0000000..8510e90
--- /dev/null
@@ -0,0 +1,57 @@
+# 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
diff --git a/contrib/psg/configs/symphony.txt b/contrib/psg/configs/symphony.txt
new file mode 100644 (file)
index 0000000..fb5c778
--- /dev/null
@@ -0,0 +1,154 @@
+# ::::::::::::::::::::::::::::::::::::::::::::::::::::::\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
diff --git a/contrib/psg/configs/symphonyPSG.txt b/contrib/psg/configs/symphonyPSG.txt
new file mode 100644 (file)
index 0000000..20b7dce
--- /dev/null
@@ -0,0 +1,155 @@
+# ::::::::::::::::::::::::::::::::::::::::::::::::::::::\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
diff --git a/contrib/psg/lib.jar b/contrib/psg/lib.jar
new file mode 100644 (file)
index 0000000..8fd65fa
Binary files /dev/null and b/contrib/psg/lib.jar differ
diff --git a/contrib/psg/platforms/psg.xml b/contrib/psg/platforms/psg.xml
new file mode 100644 (file)
index 0000000..bdd2e19
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version='1.0'?>
+<!DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid.dtd">
+<!--             _________
+                |          |
+                |  router  |
+    ____________|__________|_____________ backbone
+      |   |   |              |     |   |       
+    l0|        l1| l2|           l97| l96 |   | l99
+      |   |   |   ........   |     |   |
+      |                                |
+    c-0.me                             c-99.me 
+
+-->
+<platform version="3">
+<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"       power="1Gf"  bw="200Mbps" lat="0ms"
+        bb_bw="200Mbps" bb_lat="0ms"/>
+</AS>
+</platform>
diff --git a/contrib/psg/run.sh b/contrib/psg/run.sh
new file mode 100755 (executable)
index 0000000..ecac88c
--- /dev/null
@@ -0,0 +1,15 @@
+#!/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 peersim.Simulator $1
+echo '------------- done -------------';
+exit 0
+
+
+
+
diff --git a/contrib/psg/src/example/bittorrent/BTObserver.java b/contrib/psg/src/example/bittorrent/BTObserver.java
new file mode 100644 (file)
index 0000000..ddd38da
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * 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
diff --git a/contrib/psg/src/example/bittorrent/BitTorrent.java b/contrib/psg/src/example/bittorrent/BitTorrent.java
new file mode 100644 (file)
index 0000000..1604a4d
--- /dev/null
@@ -0,0 +1,1989 @@
+/*
+ * 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
diff --git a/contrib/psg/src/example/bittorrent/BitfieldMsg.java b/contrib/psg/src/example/bittorrent/BitfieldMsg.java
new file mode 100644 (file)
index 0000000..d459482
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * 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
diff --git a/contrib/psg/src/example/bittorrent/IntMsg.java b/contrib/psg/src/example/bittorrent/IntMsg.java
new file mode 100644 (file)
index 0000000..a10eaea
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * 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
diff --git a/contrib/psg/src/example/bittorrent/NetworkDynamics.java b/contrib/psg/src/example/bittorrent/NetworkDynamics.java
new file mode 100644 (file)
index 0000000..bdbd93a
--- /dev/null
@@ -0,0 +1,289 @@
+/*
+ * 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
diff --git a/contrib/psg/src/example/bittorrent/NetworkInitializer.java b/contrib/psg/src/example/bittorrent/NetworkInitializer.java
new file mode 100644 (file)
index 0000000..4b5ba72
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * 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;
+       }
+       
+       }
diff --git a/contrib/psg/src/example/bittorrent/NodeInitializer.java b/contrib/psg/src/example/bittorrent/NodeInitializer.java
new file mode 100644 (file)
index 0000000..df71688
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * 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
diff --git a/contrib/psg/src/example/bittorrent/PeerSetMsg.java b/contrib/psg/src/example/bittorrent/PeerSetMsg.java
new file mode 100644 (file)
index 0000000..d0e92d5
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * 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;    
+       }
+}
diff --git a/contrib/psg/src/example/bittorrent/SimpleEvent.java b/contrib/psg/src/example/bittorrent/SimpleEvent.java
new file mode 100644 (file)
index 0000000..1da537a
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * 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;       
+       }
+}
+
+
diff --git a/contrib/psg/src/example/bittorrent/SimpleMsg.java b/contrib/psg/src/example/bittorrent/SimpleMsg.java
new file mode 100644 (file)
index 0000000..cf9436e
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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;     
+       }
+}
diff --git a/contrib/psg/src/example/chord/ChordInitializer.java b/contrib/psg/src/example/chord/ChordInitializer.java
new file mode 100644 (file)
index 0000000..799b0d7
--- /dev/null
@@ -0,0 +1,72 @@
+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
diff --git a/contrib/psg/src/example/chord/ChordMessage.java b/contrib/psg/src/example/chord/ChordMessage.java
new file mode 100644 (file)
index 0000000..f87fafb
--- /dev/null
@@ -0,0 +1,12 @@
+/**\r
+ * \r
+ */\r
+package example.chord;\r
+\r
+/**\r
+ * @author Andrea\r
+ * \r
+ */\r
+public interface ChordMessage {\r
+\r
+}\r
diff --git a/contrib/psg/src/example/chord/ChordProtocol.java b/contrib/psg/src/example/chord/ChordProtocol.java
new file mode 100644 (file)
index 0000000..485c3ba
--- /dev/null
@@ -0,0 +1,358 @@
+/**\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
diff --git a/contrib/psg/src/example/chord/CreateNw.java b/contrib/psg/src/example/chord/CreateNw.java
new file mode 100644 (file)
index 0000000..9268653
--- /dev/null
@@ -0,0 +1,148 @@
+/**\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
diff --git a/contrib/psg/src/example/chord/FinalMessage.java b/contrib/psg/src/example/chord/FinalMessage.java
new file mode 100644 (file)
index 0000000..847dba9
--- /dev/null
@@ -0,0 +1,14 @@
+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
diff --git a/contrib/psg/src/example/chord/LookUpMessage.java b/contrib/psg/src/example/chord/LookUpMessage.java
new file mode 100644 (file)
index 0000000..091089e
--- /dev/null
@@ -0,0 +1,44 @@
+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
diff --git a/contrib/psg/src/example/chord/MessageCounterObserver.java b/contrib/psg/src/example/chord/MessageCounterObserver.java
new file mode 100644 (file)
index 0000000..dbcbb8f
--- /dev/null
@@ -0,0 +1,108 @@
+/**\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
diff --git a/contrib/psg/src/example/chord/NodeComparator.java b/contrib/psg/src/example/chord/NodeComparator.java
new file mode 100644 (file)
index 0000000..def16dc
--- /dev/null
@@ -0,0 +1,21 @@
+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
diff --git a/contrib/psg/src/example/chord/Parameters.java b/contrib/psg/src/example/chord/Parameters.java
new file mode 100644 (file)
index 0000000..d32d82f
--- /dev/null
@@ -0,0 +1,7 @@
+package example.chord;\r
+\r
+public class Parameters {\r
+       int pid;\r
+\r
+       int tid;\r
+}\r
diff --git a/contrib/psg/src/example/chord/TrafficGenerator.java b/contrib/psg/src/example/chord/TrafficGenerator.java
new file mode 100644 (file)
index 0000000..09c5854
--- /dev/null
@@ -0,0 +1,54 @@
+/**\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
diff --git a/contrib/psg/src/example/edaggregation/AverageED.java b/contrib/psg/src/example/edaggregation/AverageED.java
new file mode 100644 (file)
index 0000000..c5f3358
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * 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
diff --git a/contrib/psg/src/example/symphony/AdapterIterableNetwork.java b/contrib/psg/src/example/symphony/AdapterIterableNetwork.java
new file mode 100644 (file)
index 0000000..37bf104
--- /dev/null
@@ -0,0 +1,31 @@
+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
diff --git a/contrib/psg/src/example/symphony/AdapterSymphonyNodeComparator.java b/contrib/psg/src/example/symphony/AdapterSymphonyNodeComparator.java
new file mode 100644 (file)
index 0000000..b05bbb6
--- /dev/null
@@ -0,0 +1,28 @@
+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
diff --git a/contrib/psg/src/example/symphony/Handler.java b/contrib/psg/src/example/symphony/Handler.java
new file mode 100644 (file)
index 0000000..c78d774
--- /dev/null
@@ -0,0 +1,19 @@
+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
diff --git a/contrib/psg/src/example/symphony/LeaveTest.java b/contrib/psg/src/example/symphony/LeaveTest.java
new file mode 100644 (file)
index 0000000..b4c9167
--- /dev/null
@@ -0,0 +1,77 @@
+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
diff --git a/contrib/psg/src/example/symphony/Message.java b/contrib/psg/src/example/symphony/Message.java
new file mode 100644 (file)
index 0000000..5f63d11
--- /dev/null
@@ -0,0 +1,90 @@
+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
diff --git a/contrib/psg/src/example/symphony/NetworkSizeEstimatorProtocolInterface.java b/contrib/psg/src/example/symphony/NetworkSizeEstimatorProtocolInterface.java
new file mode 100644 (file)
index 0000000..ffb8ba9
--- /dev/null
@@ -0,0 +1,13 @@
+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
diff --git a/contrib/psg/src/example/symphony/RandomRouteTest.java b/contrib/psg/src/example/symphony/RandomRouteTest.java
new file mode 100644 (file)
index 0000000..fe55f33
--- /dev/null
@@ -0,0 +1,48 @@
+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
diff --git a/contrib/psg/src/example/symphony/RingRouteTest.java b/contrib/psg/src/example/symphony/RingRouteTest.java
new file mode 100644 (file)
index 0000000..06262cb
--- /dev/null
@@ -0,0 +1,150 @@
+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
diff --git a/contrib/psg/src/example/symphony/RoutingException.java b/contrib/psg/src/example/symphony/RoutingException.java
new file mode 100644 (file)
index 0000000..1b6bb9b
--- /dev/null
@@ -0,0 +1,15 @@
+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
diff --git a/contrib/psg/src/example/symphony/SimpleNetworkSizeEstimatorProtocol.java b/contrib/psg/src/example/symphony/SimpleNetworkSizeEstimatorProtocol.java
new file mode 100644 (file)
index 0000000..6d17371
--- /dev/null
@@ -0,0 +1,23 @@
+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
diff --git a/contrib/psg/src/example/symphony/SymphonyEstimationProtocol.java b/contrib/psg/src/example/symphony/SymphonyEstimationProtocol.java
new file mode 100644 (file)
index 0000000..642677d
--- /dev/null
@@ -0,0 +1,106 @@
+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