////////////////////////////////////////////////////////////////////// // RootVector.java // // --Root Node maintenance data structure used to maintain SPON-- // // // // Supervised Peer-to-peer Overlay Network (SPON) Simulator // // // // Computer Science Independent Study // // Modified by: Peter Keeler, Spring 2004 // // // // Computer Science M.S.E. Project // // Programmed by: Joey Chau // // Copyright: February, 2003 // // // // Research Advisor: Christian Scheideler // // Computer Science // // Johns Hopkins University // ////////////////////////////////////////////////////////////////////// import java.io.*; import java.net.*; import java.util.*; /** The data structure maintaing the list of root vectors known to the SPON Supervisor and provides the communcation mechanims for various join and leave processes. */ class RootVector { private Vector myVector; private String myKey; private int maxHeight; private int numberOfNodes; private boolean root; /** Create a new RootVector of size 0 on node . */ public RootVector() { myVector = new Vector(); maxHeight = 1; numberOfNodes = 0; root = false; myKey = "0.0.0.0"; } /** Create a new Root Vector of size 0 for the system supervisor @param src - String representation of the supervisor IP */ public RootVector( String src ) { myVector = new Vector(); maxHeight = -1; numberOfNodes = 0; myKey = src; root = false; } public RootVector( String src, boolean b ) { myVector = new Vector(); maxHeight = -1; numberOfNodes = 0; myKey = src; root = b; } public RootVector(int i) { myVector = new Vector(); maxHeight = i; numberOfNodes = 0; root = false; } public RootVector(String src, int i) { myVector = new Vector(); maxHeight = i; numberOfNodes = 0; root = false; myKey = src; } public int getHeight() { return maxHeight; } public Node getNode(int i) { // search for the i'th real node, ignoring empties. int k; int j; Node aNode = new Node(); for (j = 0,k=0; k < i && j < myVector.size(); j++) { aNode = (Node)myVector.elementAt(j); if (!(aNode.isEmpty())) { k++; } } return aNode; // aNode is either the ith real node, or is null. } public void removeNode(String key) { // search for the node with IP addr == key and remove it. String str; Node nullNode = new Node(); for (int i = 0; i < myVector.size(); i++) { str = ((Node) myVector.elementAt(i)).getKey(); if (key.compareToIgnoreCase(str)==0) { myVector.setElementAt(nullNode,i); numberOfNodes--; if (numberOfNodes < 0) numberOfNodes = 0; } } } public boolean isChild(String str) { // search through vector, check if str is key to any node. for (int i = 0; i < myVector.size(); i++) { if (((Node)myVector.elementAt(i)).getKey().compareToIgnoreCase(str)==0) return true; } return false; } public boolean isLeft(Node n) { for (int i = 0; i < myVector.size(); i++) { if (((Node)myVector.elementAt(i)).getKey().compareToIgnoreCase(n.getKey())==0) { if (i%2==0) return true; return false; } } return false; } public String getPos(Node n) { for (int i = 0; i < myVector.size(); i++) { if (((Node)myVector.elementAt(i)).getKey().compareToIgnoreCase(n.getKey())==0) return Integer.toString(i+4); } return "-1"; } /** In case the vector is not long enough we can grow the vector to produce more space @return boolean - true if the vector was extended */ private boolean grow() { boolean add1, add2, add3, add4; add1 = myVector.add( new Node() ); add2 = myVector.add( new Node() ); add3 = myVector.add( new Node() ); add4 = myVector.add( new Node() ); return (add1 && add2 && add3 && add4); } /** In case the vector is too long, this will collapse the higher elements to save space @return boolean - true if the vector was collapsed */ private boolean collapse() { boolean workornot; int vSize; vSize = myVector.size(); workornot = false; if( vSize >= 4 ) { Node last1 = (Node)myVector.elementAt( vSize - 1 ); Node last2 = (Node)myVector.elementAt( vSize - 2 ); Node last3 = (Node)myVector.elementAt( vSize - 3 ); Node last4 = (Node)myVector.elementAt( vSize - 4 ); if( last1.isEmpty() && last2.isEmpty() && last3.isEmpty() && last4.isEmpty()) { myVector.removeElementAt( vSize - 1 ); myVector.removeElementAt( vSize - 2 ); myVector.removeElementAt( vSize - 3 ); myVector.removeElementAt( vSize - 4 ); workornot = true; } else { workornot = false; } } else { workornot = false; } return workornot; } /** Adds a node onto the SPON network. @param ipKey - String representation of the Node wishing to join the Network @return String - a delimited string of messages to be sent to the other network members as a result of the join */ public String join( String ipKey ) { String comStack = new String(); // Check for redundancy int emptySlot; emptySlot = -1; for( int i = (myVector.size() - 1); i >= 0; i-- ) { if( ipKey.equals(( (Node)myVector.elementAt( i )).getKey())) { // Found this node already in the network: // return its parent and the permissible height. Node foundNode = (Node)myVector.elementAt(i); comStack = foundNode.getMParent(); return comStack + ";" + ((myVector.size()/4)-(i/4)+1); } if(((Node)myVector.elementAt(i)).getKey().compareToIgnoreCase("0.0.0.0")==0) { // Found an empty space to fill. emptySlot = i; } } // Vector full. If space is available for growth, grow. if( emptySlot == -1 ) { if (root || (myVector.size()/4)