⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chordnode.java

📁 p2p仿真器。开发者可以工作在覆盖层中进行创造和测试逻辑算法或者创建和测试新的服务。PlanetSim还可以将仿真代码平稳转换为在Internet上的实验代码
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
package planet.chord;
import java.math.BigInteger;
import java.util.Collection;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;

import planet.chord.message.BroadcastMessage;
import planet.chord.message.IdMessage;
import planet.chord.message.NodeMessage;
import planet.chord.message.SuccListMessage;
import planet.commonapi.EndPoint;
import planet.commonapi.Id;
import planet.commonapi.Message;
import planet.commonapi.Node;
import planet.commonapi.NodeHandle;
import planet.commonapi.RouteMessage;
import planet.commonapi.exception.InitializationException;
import planet.commonapi.results.ResultsConstraint;
import planet.commonapi.results.ResultsEdge;
import planet.generic.commonapi.factory.GenericFactory;
import planet.simulate.Globals;
import planet.simulate.Logger;
import planet.simulate.MessageListener;
import planet.simulate.Results;
import planet.util.Properties;
import planet.util.Queue;
import planet.util.timer.TimerTaskImpl;


/**
 * 
 * A Chord node is single entity in the chord network. It extends of the class
 * NodeImpl and specializes following the lookup Chord protocol. Moreover, the
 * stabilization implementation, producing the periodic stabilition events.
 * 
 * @author <a href="mailto:Ruben.Mondejar@estudiants.urv.es">Ruben Mondejar</a>
 * @author <a href="mailto:cpairot@etse.urv.es">Carles Pairot</a>
 * @author <a href="mailto:jordi.pujol@estudiants.urv.es">Jordi Pujol</a>
 * @author <a href="mailto:marc.sanchez@estudiants.urv.es">Marc Sanchez</a>
 *  
 */
public class ChordNode extends planet.generic.commonapi.NodeImpl {
	
	/* ******************  CONSTANTS FOR MODE OF ROUTEMESSAGE *******/
	
	/**
	 * Mode value: Defines the start of communication that requires 
	 * response (REPLY). 
	 */
	public final static int REQUEST		= 0;
	/**
	 * Mode value: Defines the response of a communication.
	 */
	public final static int REPLY		= 1;
	/**
	 * Mode value: Defines a message's mode that requires only
	 * communication on one way.
	 */
	public final static int REFRESH  	= 2;		
	
	/* END ******************  CONSTANTS FOR MODE OF ROUTEMESSAGE *******/
	
	/* ******************  CONSTANTS FOR TYPE OF ROUTEMESSAGE *******/
	/**
	 * Type value: First message that is send by any node to get its
	 * inmediate successor.
	 */
	public final static int FIND_SUCC 	= 0;
	/**
	 * Type value: Start a set of messages that permits to find the
	 * inmediate successor of any new incoming node to the network.
	 */
	public final static int FIND_PRE   	= 1;
	/**
	 * Type value: Informs to the node that receives this message its
	 * new inmediate successor.
	 */
	public final static int SET_SUCC   	= 2;
	/**
	 * Type value: Informs to the node that receive this message its
	 * new inmediate predecessor. This type forces to node to change its
	 * predecessor.
	 */
	public final static int SET_PRE    	= 3;
	/**
	 * Type value: Start a set of messages that permits to find the
	 * inmediate node in charge of any key.
	 */
	public final static int GET_PRE    	= 4;
	/**
	 * Type value: Informs to the node that receive this message its
	 * inmediate predecessor. This type permits to the node to evaluate
	 * if this notification informs really of the predecessor of the node.
	 */
	public final static int NOTIFY     	= 5;
	/**
	 * Type value: Start a set of messages that permits the harvesting of
	 * successors of the node that send originally this message.
	 */
	public final static int SUCC_LIST  	= 6;
	/**
	 * Type value: The message with this type identifies a broadcast message.
	 */
	public final static int BROADCAST  	= 7;
	/**
	 * Type value: It identifies that this message contains an application 
	 * level Message. 
	 */
	public final static int DATA 		= 8;	
	
	/* END ******************  CONSTANTS FOR TYPE OF ROUTEMESSAGE *******/
	
	/* ******************  CONSTANTS FOR TYPE/MODE OF ROUTEMESSAGE *******/
	/**
	 * This String contains a string representation of each of types
	 * and modes values of the RouteMessage.
	 */
	public final static String[] TYPES = {
			"FIND_SUCC", "FIND_PRE", "SET_SUCC", "SET_PRE", "GET_PRE", "NOTIFY",
			"SUCC_LIST", "BROADCAST", "DATA"}; 
	
	/**
	 * This String contains a string representation of each mode
	 * value of the RouteMessage.
	 */
	public final static String[] MODES = {"REQUEST", "REPLY", "REFRESH" };
	
	/* END ******************  CONSTANTS FOR TYPE/MODE OF ROUTEMESSAGE *******/
	
	/**
	 * Return a RouteMessage with the specified values. If there are RouteMessages free,
	 * just build a new one. For generate new instances of RouteMessage will be used
	 * the implementation class that appears in properties file.
	 * @param appId Application Id name.
	 * @param from Source node.
	 * @param to Destination node.
	 * @param nextHop NextHop node.
	 * @return A RouteMessage with the specified values.
	 */
	public static RouteMessage getDataMessage(String appId,
			NodeHandle from, NodeHandle to, NodeHandle nextHop, Message msg) 
				throws InitializationException {
	  	RouteMessage toReturn = GenericFactory.getMessage(GenericFactory.generateKey(), from, to, nextHop, null, DATA, REQUEST, appId);
	  	toReturn.setMessage(msg);
	  	return toReturn;
	}
	
	/**
	 * Return a RouteMessage with the specified values. If there are RouteMessages free,
	 * just build a new one. For generate new instances of RouteMessage will be used
	 * the implementation class that appears in properties file.
	 * @param appId Application Id name.
	 * @param from Source node.
	 * @param to Destination node.
	 * @param nextHop NextHop node.
	 * @return A RouteMessage with the specified values.
	 */
	public static RouteMessage getBroadcastMessage(String appId,
			NodeHandle from, NodeHandle to, NodeHandle nextHop, Message msg) 
				throws InitializationException {
	  	RouteMessage toReturn = GenericFactory.getMessage("",from,to,nextHop,null,BROADCAST,REFRESH,appId);
	  	toReturn.setMessage(msg);
	  	return toReturn;
	}
	
	
	/**
     * Maximum Id value with the current configuration.
	 */
	protected Id MAX;
    /**
     * Index to use within stabilization process onto the finger table.
     */
	protected int nullPointers = 0;
	/**
	 * Detect the number of finger changes only on one simulation step.
	 */
	protected int fingerChanges = 0;
	/**
	 * Number of simulation steps without changes on finger table.
	 */
	protected int stabRate = 0;
    /**
     * Number of bits per key to use as current configuration.
     */
    protected int bitsPerKey = ((ChordProperties)Properties.overlayPropertiesInstance).bitsPerKey;
	/**
	 * Number of simulation steps without changes on finger table, that
	 * represents a real stabilization of this node.
	 */
	protected int realStabilizationRate = 
		((ChordProperties)Properties.overlayPropertiesInstance).stabilizeSteps * 
		((ChordProperties)Properties.overlayPropertiesInstance).bitsPerKey * 2;
	/**
     * The current predecessor in the Chord ring.
	 */
	protected NodeHandle predecessor;
    /**
     * Flag that shows when this node has failed.
     */
	protected boolean hasFailed; // For Failed Case
    /**
     * Flag that shows when this node has leaved.
     */
	protected boolean hasLeaved; // For Leaved Case
	/** Shows when has been received the GET_PRE response, requested on the stabilize() method to find the successor. */
	protected boolean hasReceivedSucc;
    /**
     * Flag that optimizes the number of invokations of <b>closestPrecedingFinger</b>
     * method.
     */
	private boolean cpfFound; 
	
	
	/**
     * Current finger table.
	 */
	public NodeHandle[] finger;
	/**
     * The starting indices for the finger table (as Finger[k].start).
	 */ 
	public Id[] start;
	/**
     * Current successor list.
	 */
	public Vector succList;	

	/**
	 * Temporal use in Common API methods.
	 */
	protected Vector auxCAPI;
	public Id deux;
	protected NodeHandle[] temp;
	
	
	/**
	 * Constructor, create a new BadChordNode instance with this node Id
	 */
	public ChordNode() throws InitializationException {
        super();
        deux = GenericFactory.buildId(ChordId.TWO_CHORD);
		finger = new NodeHandle[bitsPerKey];
		start = new Id[bitsPerKey];
		temp = new NodeHandle[3];
		succList = new Vector(((ChordProperties)Properties.overlayPropertiesInstance).succListMax+2);
		hasLeaved = false;
		hasFailed = false;
		hasReceivedSucc = true;   //permits the send
        
        //add stabilize timer
        setTimer(new StabilizeTask(),  ((ChordProperties)Properties.overlayPropertiesInstance).stabilizeSteps,
                ((ChordProperties)Properties.overlayPropertiesInstance).stabilizeSteps);
        // add fix finger timer
        setTimer(new FixFingerTask(),  ((ChordProperties)Properties.overlayPropertiesInstance).fixFingerSteps,
                ((ChordProperties)Properties.overlayPropertiesInstance).fixFingerSteps);

	}
	
	/**
	 * Sets the predecessor node
	 * 
	 * @param handle
	 *            NodeHandle of the predecessor
	 */
	public void setPred(NodeHandle handle) {
		predecessor = handle;
	}
	/**
	 * Sets the successor node
	 * 
	 * @param handle
	 *            NodeHandle of the successor
	 */
	public void setSucc(NodeHandle handle) {
		finger[0] = handle;
        
        //always the successor at the first position
        if (succList.size()>0)
            succList.add(0,handle);
        else
            succList.add(handle);
	}
    
    /**
     * Deletes all NodeHandles that exceeds the required size of successor list.
     */
    protected void cleanSuccList()
    {
        int succListMax = ((ChordProperties)Properties.overlayPropertiesInstance).succListMax;
        for (int i=succList.size(); i > succListMax; i--)
        {
            succList.remove(i-1);
        }
    }
    
	/**
	 * Returns the NodeHandle of the present identification of the precursor of the
	 * node
	 * 
	 * @return predeccesor NodeHandle
	 */
	public NodeHandle getPred() {
		return predecessor;
	}
	/**
	 * Returns the NodeHandle of the present identification of the successor of the
	 * node
	 * 
	 * @return predeccesor NodeHandle
	 */
	public NodeHandle getSucc() {
		return finger[0];
	}
	/**
	 * Returns the successor list of the present node
	 * 
	 * @param max
	 *            number of the elements to return
	 * @return successor list Vector
	 */
	public Vector getSuccList(int max) {
		Iterator it = succList.iterator();
		Vector sl = new Vector();
		int i = 0;
		while (it.hasNext() && i < max)
			sl.add(it.next());
		return sl;
	}
	
	/**
	 * Clears the counter of the finger table changes
	 */
	protected void clearFingerChanges() {
		fingerChanges = 0;
	}
	/**
	 * Returns the count of the finger table changes
	 * 
	 * @return finger_changes int counter
	 */
	protected int getFingerChanges() {
		return fingerChanges;
	}
	/**
	 * Sets a especific finger of the finger table
	 * @param pos position of the finger
	 * @param handle new NodeHandle to change
	 */
	protected void setFinger(int pos, NodeHandle handle) {
		if (finger[pos] == null || !finger[pos].equals(handle)) {
			fingerChanges++;
			finger[pos] = handle;
		}
	}
	
	public Hashtable getInfo() {
		Hashtable info = new Hashtable();
		info.put("predecessor", predecessor);
		info.put("finger", finger);
		info.put("start", start);
		info.put("succ_list", succList);
		return info;
	}
	/**
	 * Shows for System.out all information of the node, including finger
	 * table.
	 */
	public void printNode() {
		System.out.println("######\nNode:        " + getId());
		System.out.println("Finger table:");
		for (int i = 0; i < finger.length; i++) {
			if (finger[i] != null)
				System.out.println(start[i] + " : " + finger[i]);
			else
				System.out.println(" finger [" + i + "] == null ");
			System.out.println("-----------");
		}
		System.out.println("Predecessor: " + predecessor);
		System.out.println("Succ-List: " + succList);
		System.out.println("###### END OF NODE\n");
	}
	/**
	 * Shows for System.out only the owner Id, its predecessor and successor.
	 */
	public void prettyPrintNode() {
		System.out.println("######\nNode:        " + getId());
		System.out.println("Successor:   " + finger[0]);
		System.out.println("Predecessor: " + predecessor);
		System.out.println("###### END OF NODE\n");
	}

	/**
	 * Finds the successor of a node. If the result if null because the
	 * information its not contain in the finger table, it generate a request
	 * message and the response message content the real result
	 * 
	 * @param handle
	 *             NodeHandle of the one node
	 * @return successor Id of the node successor
	 */
	protected NodeHandle findSuccessor(NodeHandle handle) {
		if (predecessor != null && handle.getId().betweenE(predecessor.getId(), this.id)) {
			return this.nodeHandle;
		} else {
			return findPredecessor(handle);
		}
	}
	/**
	 * Finds the predecessor of a node. If the result if null because the
	 * information its not contain in the finger table, it generate a request
	 * message and the response message content the real result
	 * 
	 * @param handle
	 *            NodeHandle of the one node
	 * @return successor NodeHandle of the node predecessor
	 */
	protected NodeHandle findPredecessor(NodeHandle handle) {
		if (handle.getId().equals(this.id)) {
			return this.nodeHandle; //return predecessor.successor();
		} else if (finger[0] != null && handle.getId().betweenE(this.id, finger[0].getId())) {
			return finger[0];
		} else {
			return null;
		}
	}
	
	/**
	 * Finds the closest preceding finger of a node
	 * 
	 * @param id
	 *            Id of the one node
	 * @return successor NodeHandle of the node successor
	 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -