Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
peersimgrid release 1.0
[simgrid.git] / contrib / psg / src / example / symphony / SymphonyNetworkBuilder.java
diff --git a/contrib/psg/src/example/symphony/SymphonyNetworkBuilder.java b/contrib/psg/src/example/symphony/SymphonyNetworkBuilder.java
new file mode 100644 (file)
index 0000000..a012d60
--- /dev/null
@@ -0,0 +1,157 @@
+package example.symphony;\r
+\r
+import java.util.Collection;\r
+import java.util.Comparator;\r
+import java.util.LinkedList;\r
+import java.util.logging.Level;\r
+import java.util.logging.Logger;\r
+\r
+import example.symphony.SymphonyProtocol.BootstrapStatus;\r
+import peersim.config.Configuration;\r
+import peersim.core.CommonState;\r
+import peersim.core.Control;\r
+import peersim.core.Network;\r
+import peersim.core.Node;\r
+\r
+/**\r
+ * Inizializer that create the initial ring\r
+ *\r
+ * @author Andrea Esposito <and1989@gmail.com>\r
+ */\r
+public class SymphonyNetworkBuilder implements Control {\r
+\r
+    private static final String PAR_SYMHONY = "symphony";\r
+    private static final String PAR_LONG_LINK = "createLongLinks";\r
+    private static final String PAR_MAX_ATTEMPTS = "attempts";\r
+    private final int symphonyID;\r
+    private final boolean createLongRangeLinks;\r
+    private final int MAX_ATTEMPTS;\r
+\r
+    public SymphonyNetworkBuilder(String prefix) {\r
+\r
+        symphonyID = Configuration.getPid(prefix + "." + PAR_SYMHONY);\r
+        createLongRangeLinks = Configuration.getBoolean(prefix + "." + PAR_LONG_LINK, true);\r
+        MAX_ATTEMPTS = Configuration.getInt(prefix + "." + PAR_MAX_ATTEMPTS, 5);\r
+    }\r
+\r
+    public boolean execute() {\r
+\r
+        // Sort the network for convenience (from 0.0 to 1.0)\r
+        Network.sort(new Comparator<Node>() {\r
+\r
+            public int compare(Node o1, Node o2) {\r
+\r
+                SymphonyProtocol symphony1 = (SymphonyProtocol) o1.getProtocol(symphonyID);\r
+                SymphonyProtocol symphony2 = (SymphonyProtocol) o2.getProtocol(symphonyID);\r
+\r
+                Double identifier1 = symphony1.getIdentifier();\r
+                Double identifier2 = symphony2.getIdentifier();\r
+\r
+                return identifier1.compareTo(identifier2);\r
+            }\r
+        });\r
+\r
+        int numShortLinksPerSide = ((SymphonyProtocol) Network.get(0).getProtocol(symphonyID)).numberShortRangeLinksPerSide;\r
+\r
+        for (int i = 0; i < Network.size(); i++) {\r
+\r
+            Node node = Network.get(i);\r
+            SymphonyProtocol symphonyNode = (SymphonyProtocol) node.getProtocol(symphonyID);\r
+\r
+            // Create the short links\r
+            for (int j = 1; j <= numShortLinksPerSide; j++) {\r
+\r
+                int pos = i - j;\r
+                pos = pos < 0 ? Network.size() + pos : pos;\r
+                symphonyNode.rightShortRangeLinks.add(new Tuple<Node, BootstrapStatus>(Network.get(pos), BootstrapStatus.ONLINE));\r
+\r
+                pos = (i + j) % Network.size();\r
+                symphonyNode.leftShortRangeLinks.add(new Tuple<Node, BootstrapStatus>(Network.get(pos), BootstrapStatus.ONLINE));\r
+            }\r
+\r
+            symphonyNode.loggedIntoNetwork = SymphonyProtocol.BootstrapStatus.ONLINE;\r
+        }\r
+\r
+        /*\r
+         * UPDATE: Putted a flag to decide if perform this part of code or not at configuration\r
+         * time. At default i create the long range links.\r
+         *\r
+         * The Long Range Links could be left to the networkmanager but the tests that we'll do have\r
+         * to put into account that in an initial phase will be some message exchanging to create\r
+         * the long range links and so the latency is faked... for that reason the long range links\r
+         * are created manually here such a way to have a complete symphony network from the\r
+         * beginning.\r
+         */\r
+        if (createLongRangeLinks) {\r
+            for (Node node : new AdapterIterableNetwork()) {\r
+\r
+                SymphonyProtocol symphonyNode = (SymphonyProtocol) node.getProtocol(symphonyID);\r
+\r
+                // Create the long links\r
+                int k = (int) Math.ceil(Math.log(Network.size()) / Math.log(2));\r
+\r
+                if (symphonyNode.fixedLongRangeLinks) {\r
+                    k = symphonyNode.numberFixedLongRangeLinks;\r
+                }\r
+\r
+                Collection<Node> allShortLinks = new LinkedList<Node>();\r
+                for (Tuple<Node, BootstrapStatus> shortTuple : symphonyNode.leftShortRangeLinks) {\r
+                    allShortLinks.add(shortTuple.x);\r
+                }\r
+                for (Tuple<Node, BootstrapStatus> shortTuple : symphonyNode.rightShortRangeLinks) {\r
+                    allShortLinks.add(shortTuple.x);\r
+                }\r
+\r
+                int j = 0;\r
+                int attempts = MAX_ATTEMPTS;\r
+                while (j <= k) {\r
+\r
+                    double distance = Math.exp(k * (CommonState.r.nextDouble() - 1.0));\r
+                    double targetIdentifier = (symphonyNode.getIdentifier() + distance) % 1;\r
+\r
+                    Node targetNode;\r
+                    try {\r
+\r
+                        // use the unidirectional routing because i want to catch the manager\r
+                        targetNode = symphonyNode.findClosestNode(targetIdentifier, new AdapterIterableNetwork(), true);\r
+                        SymphonyProtocol symphonyTargetNode = (SymphonyProtocol) targetNode.getProtocol(symphonyID);\r
+                        if (!targetNode.equals(node)\r
+                                && !symphonyNode.longRangeLinksOutgoing.contains(targetNode)\r
+                                && symphonyTargetNode.longRangeLinksIncoming.size() < (2 * k)\r
+                                && !allShortLinks.contains(targetNode)) {\r
+\r
+                            boolean fresh = symphonyTargetNode.longRangeLinksIncoming.add(node);\r
+\r
+                            if (fresh) {\r
+                                j++;\r
+                                attempts = MAX_ATTEMPTS;\r
+                                symphonyNode.longRangeLinksOutgoing.add(targetNode);\r
+                            } else {\r
+                                attempts--;\r
+                                if (attempts <= 0) { // Because i don't want to loop i try a finite number of times\r
+                                    attempts = MAX_ATTEMPTS;\r
+                                    j++;\r
+                                }\r
+\r
+                            }\r
+                        } else {\r
+                            attempts--;\r
+                            if (attempts <= 0) { // Because i don't want to loop i try a finite number of times\r
+                                attempts = MAX_ATTEMPTS;\r
+                                j++;\r
+                            }\r
+\r
+                        }\r
+                    } catch (RoutingException ex) {\r
+                        Logger.getLogger(SymphonyNetworkBuilder.class.getName()).log(Level.SEVERE, null, ex);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+\r
+        // Shuffle\r
+        Network.shuffle();\r
+\r
+        return false;\r
+    }\r
+}\r