Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
peersimgrid release 1.0
[simgrid.git] / contrib / psg / src / example / chord / ChordProtocol.java
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