Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
peersimgrid release 1.0
[simgrid.git] / contrib / psg / src / example / symphony / SymphonyEstimationProtocol.java
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
+            if (tuple.y == SymphonyProtocol.BootstrapStatus.OFFLINE) {\r
+                offlineNeighbors.add(tuple);\r
+            }\r
+        }\r
+        leftList.removeAll(offlineNeighbors);\r
+        offlineNeighbors.clear();\r
+        for (Tuple<Node, SymphonyProtocol.BootstrapStatus> tuple : rightList) {\r
+            if (tuple.y == SymphonyProtocol.BootstrapStatus.OFFLINE) {\r
+                offlineNeighbors.add(tuple);\r
+            }\r
+        }\r
+        rightList.removeAll(offlineNeighbors);\r
+\r
+        // Sort the neighbours based on the distance from me\r
+        Comparator<Tuple<Node, SymphonyProtocol.BootstrapStatus>> comparator = new AdapterSymphonyNodeComparator(new SymphonyNodeComparator(symphonyID, symphony.getIdentifier()));\r
+        Collections.sort(leftList, comparator);\r
+        Collections.sort(rightList, comparator);\r
+\r
+        // Calculate the variables to estimated the network size\r
+        double Xs = 0;\r
+        int countS = 0;\r
+\r
+        List<Tuple<Node, SymphonyProtocol.BootstrapStatus>> appoList[] = new List[2];\r
+        appoList[0] = leftList;\r
+        appoList[1] = rightList;\r
+\r
+        double[] appoPrecIdentifier = new double[]{symphony.getIdentifier(), symphony.getIdentifier()};\r
+        int[] appoCurrentIndex = new int[]{0, 0};\r
+\r
+        int realS = (int) (s <= 0 ? Math.log(Network.size() / Math.log(2)) : s);\r
+\r
+        for (int i = 0; i < realS; i++) {\r
+            double precIdentifier = appoPrecIdentifier[i % 2];\r
+            int currentIndex = appoCurrentIndex[i % 2];\r
+            List<Tuple<Node, SymphonyProtocol.BootstrapStatus>> currentList = appoList[i % 2];\r
+\r
+            try {\r
+                double currentIdentifier = ((SymphonyProtocol) currentList.get(currentIndex).x.getProtocol(symphonyID)).getIdentifier();\r
+\r
+                appoPrecIdentifier[i % 2] = currentIdentifier;\r
+                appoCurrentIndex[i % 2] = appoCurrentIndex[i % 2] + 1;\r
+\r
+                double distance = Math.abs(currentIdentifier - precIdentifier);\r
+                Xs += Math.min(distance, 1.0 - distance);\r
+                countS++;\r
+            } catch (IndexOutOfBoundsException ex) {\r
+                // Simply i skip the counting\r
+            }\r
+        }\r
+\r
+        int ret = Xs == 0 ? 0 : (int) Math.round(countS / Xs);\r
+\r
+        return ret;\r
+    }\r
+\r
+    @Override\r
+    public Object clone() {\r
+        return this;\r
+    }\r
+}\r