1 package example.symphony;
\r
3 import java.util.Collection;
\r
4 import java.util.Comparator;
\r
5 import java.util.LinkedList;
\r
6 import java.util.logging.Level;
\r
7 import java.util.logging.Logger;
\r
9 import example.symphony.SymphonyProtocol.BootstrapStatus;
\r
10 import peersim.config.Configuration;
\r
11 import peersim.core.CommonState;
\r
12 import peersim.core.Control;
\r
13 import peersim.core.Network;
\r
14 import peersim.core.Node;
\r
17 * Inizializer that create the initial ring
\r
19 * @author Andrea Esposito <and1989@gmail.com>
\r
21 public class SymphonyNetworkBuilder implements Control {
\r
23 private static final String PAR_SYMHONY = "symphony";
\r
24 private static final String PAR_LONG_LINK = "createLongLinks";
\r
25 private static final String PAR_MAX_ATTEMPTS = "attempts";
\r
26 private final int symphonyID;
\r
27 private final boolean createLongRangeLinks;
\r
28 private final int MAX_ATTEMPTS;
\r
30 public SymphonyNetworkBuilder(String prefix) {
\r
32 symphonyID = Configuration.getPid(prefix + "." + PAR_SYMHONY);
\r
33 createLongRangeLinks = Configuration.getBoolean(prefix + "." + PAR_LONG_LINK, true);
\r
34 MAX_ATTEMPTS = Configuration.getInt(prefix + "." + PAR_MAX_ATTEMPTS, 5);
\r
37 public boolean execute() {
\r
39 // Sort the network for convenience (from 0.0 to 1.0)
\r
40 Network.sort(new Comparator<Node>() {
\r
42 public int compare(Node o1, Node o2) {
\r
44 SymphonyProtocol symphony1 = (SymphonyProtocol) o1.getProtocol(symphonyID);
\r
45 SymphonyProtocol symphony2 = (SymphonyProtocol) o2.getProtocol(symphonyID);
\r
47 Double identifier1 = symphony1.getIdentifier();
\r
48 Double identifier2 = symphony2.getIdentifier();
\r
50 return identifier1.compareTo(identifier2);
\r
54 int numShortLinksPerSide = ((SymphonyProtocol) Network.get(0).getProtocol(symphonyID)).numberShortRangeLinksPerSide;
\r
56 for (int i = 0; i < Network.size(); i++) {
\r
58 Node node = Network.get(i);
\r
59 SymphonyProtocol symphonyNode = (SymphonyProtocol) node.getProtocol(symphonyID);
\r
61 // Create the short links
\r
62 for (int j = 1; j <= numShortLinksPerSide; j++) {
\r
65 pos = pos < 0 ? Network.size() + pos : pos;
\r
66 symphonyNode.rightShortRangeLinks.add(new Tuple<Node, BootstrapStatus>(Network.get(pos), BootstrapStatus.ONLINE));
\r
68 pos = (i + j) % Network.size();
\r
69 symphonyNode.leftShortRangeLinks.add(new Tuple<Node, BootstrapStatus>(Network.get(pos), BootstrapStatus.ONLINE));
\r
72 symphonyNode.loggedIntoNetwork = SymphonyProtocol.BootstrapStatus.ONLINE;
\r
76 * UPDATE: Putted a flag to decide if perform this part of code or not at configuration
\r
77 * time. At default i create the long range links.
\r
79 * The Long Range Links could be left to the networkmanager but the tests that we'll do have
\r
80 * to put into account that in an initial phase will be some message exchanging to create
\r
81 * the long range links and so the latency is faked... for that reason the long range links
\r
82 * are created manually here such a way to have a complete symphony network from the
\r
85 if (createLongRangeLinks) {
\r
86 for (Node node : new AdapterIterableNetwork()) {
\r
88 SymphonyProtocol symphonyNode = (SymphonyProtocol) node.getProtocol(symphonyID);
\r
90 // Create the long links
\r
91 int k = (int) Math.ceil(Math.log(Network.size()) / Math.log(2));
\r
93 if (symphonyNode.fixedLongRangeLinks) {
\r
94 k = symphonyNode.numberFixedLongRangeLinks;
\r
97 Collection<Node> allShortLinks = new LinkedList<Node>();
\r
98 for (Tuple<Node, BootstrapStatus> shortTuple : symphonyNode.leftShortRangeLinks) {
\r
99 allShortLinks.add(shortTuple.x);
\r
101 for (Tuple<Node, BootstrapStatus> shortTuple : symphonyNode.rightShortRangeLinks) {
\r
102 allShortLinks.add(shortTuple.x);
\r
106 int attempts = MAX_ATTEMPTS;
\r
109 double distance = Math.exp(k * (CommonState.r.nextDouble() - 1.0));
\r
110 double targetIdentifier = (symphonyNode.getIdentifier() + distance) % 1;
\r
115 // use the unidirectional routing because i want to catch the manager
\r
116 targetNode = symphonyNode.findClosestNode(targetIdentifier, new AdapterIterableNetwork(), true);
\r
117 SymphonyProtocol symphonyTargetNode = (SymphonyProtocol) targetNode.getProtocol(symphonyID);
\r
118 if (!targetNode.equals(node)
\r
119 && !symphonyNode.longRangeLinksOutgoing.contains(targetNode)
\r
120 && symphonyTargetNode.longRangeLinksIncoming.size() < (2 * k)
\r
121 && !allShortLinks.contains(targetNode)) {
\r
123 boolean fresh = symphonyTargetNode.longRangeLinksIncoming.add(node);
\r
127 attempts = MAX_ATTEMPTS;
\r
128 symphonyNode.longRangeLinksOutgoing.add(targetNode);
\r
131 if (attempts <= 0) { // Because i don't want to loop i try a finite number of times
\r
132 attempts = MAX_ATTEMPTS;
\r
139 if (attempts <= 0) { // Because i don't want to loop i try a finite number of times
\r
140 attempts = MAX_ATTEMPTS;
\r
145 } catch (RoutingException ex) {
\r
146 Logger.getLogger(SymphonyNetworkBuilder.class.getName()).log(Level.SEVERE, null, ex);
\r