--- /dev/null
+/**\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