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

📄 references.java

📁 Chord package into p2psim
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
					+ newReference.getNodeID().toString()
					+ " to finger table and successor list. Whether it fit "
					+ "or not depends on those data structures.");
		}
	}

	/**
	 * Removes the given node reference from the finger table and the successor
	 * list. If the given reference is the current predecessor, the predecessor
	 * reference will be <code>null</code> afterwards.
	 * 
	 * @param oldReference
	 *            Reference to remove from ALL data structures.
	 * @throws NullPointerException
	 *             If reference to remove is <code>null</code>.
	 */
	final synchronized void removeReference(Node oldReference) {

		if (oldReference == null) {
			NullPointerException e = new NullPointerException(
					"Reference to remove must not be null!");
			this.logger.error("Null pointer", e);
			throw e;
		}

		this.fingerTable.removeReference(oldReference);
		this.successorList.removeReference(oldReference);

		if (oldReference.equals(this.getPredecessor())) {
			this.predecessor = null;
		}

		disconnectIfUnreferenced(oldReference);

		if (this.logger.isEnabledFor(DEBUG)) {
			this.logger
					.debug("Attempted to remove reference "
							+ oldReference
							+ " from all data structures including predecessor reference.");
		}
	}

	/**
	 * Closes the connection to the given reference, if it is not kept in any
	 * data structure (ie. finger table, successor list, predecessor) any more.
	 * 
	 * @param removedReference
	 *            Node to which the connection shall be closed, if there exists
	 *            no reference any more.
	 * @throws NullPointerException
	 *             If given reference is null.
	 */
	void disconnectIfUnreferenced(Node removedReference) {
		if (removedReference == null) {
			NullPointerException e = new NullPointerException(
					"Reference may not be null!");
			this.logger.error("Null pointer", e);
			throw e;
		}

		if (!this.containsReference(removedReference)) {
			if (!(removedReference instanceof Proxy)) {
				this.logger
						.error("Attempt to disconnect unused reference failed");
				throw new RuntimeException("Reference should be of type Proxy");
			}
			this.logger.debug("Disconnecting unused reference on node "
					+ removedReference);
			removedReference.disconnect();
		}
	}

	/**
	 * Determines this node's direct successor and returns it. If no successor
	 * is known, <code>null</code> is returned.
	 * 
	 * @return The local node's direct successor, or <code>null</code> if no
	 *         successor is known.
	 */
	final synchronized Node getSuccessor() {
		// direct successor is the first entry in my successor list
		return this.successorList.getDirectSuccessor();
	}

	/**
	 * Returns a formatted string of the IDs of all references stored on this
	 * node. This includes references in the finger table and successor list as
	 * well as the predecessor.
	 * 
	 * @return Formatted string of references.
	 */
	public synchronized String toString() {
		StringBuilder result = new StringBuilder("Node: "
				+ this.localID.toString() + ", " + this.localURL + "\n");
		result.append(this.fingerTable.toString());

		result.append(this.successorList.toString());
		result.append("Predecessor: "
				+ (this.predecessor == null ? "null" : ""
						+ this.predecessor.getNodeID() + ", "
						+ this.predecessor.getNodeURL()));
		return result.toString();
	}

	/**
	 * Returns the reference on this node's predecessor, if available. If no
	 * predecessor exists for this node, <code>null</code> is returned.
	 * 
	 * @return Reference on this node's predecessor, if available. If no
	 *         predecessor exists for this node, <code>null</code> is
	 *         returned.
	 */
	final synchronized Node getPredecessor() {
		return this.predecessor;
	}

	/**
	 * Sets the given reference as this node's predecessor. If the former value
	 * of this predecessor's node was <code>null</code> and if this reference
	 * is not used any more (eg. in finger table or successor list), the
	 * connection to it is closed.
	 * 
	 * @param potentialPredecessor
	 *            Reference on the node to be set as new predecessor; may not be
	 *            null
	 * @throws NullPointerException
	 *             If potential predecessor is null.
	 */
	final synchronized void setPredecessor(Node potentialPredecessor) {

		if (potentialPredecessor == null) {
			NullPointerException e = new NullPointerException(
					"Potential predecessor of method setPredecessor may not be "
							+ "null!");
			this.logger.error("Null pointer", e);
			throw e;
		}
		this.checkIfProxy(potentialPredecessor);

		boolean info = this.logger.isEnabledFor(INFO);
		if (!(potentialPredecessor.equals(this.predecessor))) {
			Node formerPredecessor = this.predecessor;
			this.predecessor = potentialPredecessor;
			if (formerPredecessor != null) {
				this.disconnectIfUnreferenced(formerPredecessor);
				/*
				 * The replicas, which are in the range between the old and the
				 * new predecessor, on the last successor of this node have to
				 * be removed if the successor list is full. => capacity of sl ==
				 * length of sl.
				 */
				int sLSize = this.successorList.getSize();
				if (this.successorList.getCapacity() == sLSize) {
					Node lastSuccessor = this.successorList.getReferences()
							.get(sLSize - 1);
					try {
						lastSuccessor.removeReplicas(this.predecessor
								.getNodeID(), new HashSet<Entry>());
					} catch (CommunicationException e) {
						logger
								.warn(
										"Could not remove replicas on last predecessor",
										e);
					}
				}
				if (this.logger.isEnabledFor(DEBUG)) {
					this.logger.debug("Old predecessor " + formerPredecessor
							+ " was replaced by " + potentialPredecessor);
				}
			} else {
				if (info) {
					this.logger.info("Predecessor reference set to "
							+ potentialPredecessor + "; was null before.");
				}
				Set<Entry> entriesToRep = this.entries.getEntriesInInterval(
						this.predecessor.getNodeID(), this.localID);
				List<Node> successors = this.successorList.getReferences();
				for (Node successor : successors) {
					try {
						successor.insertReplicas(entriesToRep);
					} catch (CommunicationException e) {
						this.logger.warn(
								"Damn. Could not replicate to successor "
										+ successor.getNodeID(), e);
					}
				}
			}
		}
	}

	/**
	 * Returns an unmodifiable list of this node's successors.
	 * 
	 * @return Unmodifiable successor list.
	 */
	final synchronized List<Node> getSuccessors() {
		return this.successorList.getReferences();
	}

	/**
	 * Determines if the given reference is contained in any one data structure,
	 * ie. finger table, successor list, or predecessor reference.
	 * 
	 * @param newReference
	 *            Reference to look up.
	 * @throws NullPointerException
	 *             If given reference is <code>null</code>.
	 * @return <code>true</code> if the reference is contained and
	 *         <code>false</code> if not.
	 */
	final synchronized boolean containsReference(Node newReference) {
		if (newReference == null) {
			NullPointerException e = new NullPointerException(
					"Reference to look up must not be null!");
			this.logger.error("Null pointer", e);
			throw e;
		}
		return (this.fingerTable.containsReference(newReference)
				|| this.successorList.containsReference(newReference) || newReference
				.equals(this.predecessor));
	}

	/**
	 * Returns a formatted string of this node's finger table.
	 * 
	 * @return String representation of finger table.
	 */
	final String printFingerTable() {
		return this.fingerTable.toString();
	}

	/**
	 * Returns a formatted string of this node's successor list.
	 * 
	 * @return String representation of successor list.
	 */
	final String printSuccessorList() {
		return this.successorList.toString();
	}

	/**
	 * Adds the given node reference to the finger table and successor list AND
	 * sets it as new predecessor reference, if appropriate. Appropriateness is
	 * given if either the former predecessor reference was <code>null</code>
	 * or the new reference's ID is located between the old predecessor ID and
	 * this node's ID. Even if not appropriate as predecessor, the reference is
	 * added to finger table and successor list.
	 * 
	 * @param potentialPredecessor
	 *            Reference which should be this node's predecessor.
	 * @throws NullPointerException
	 *             If the given reference is <code>null</code>.
	 */
	void addReferenceAsPredecessor(Node potentialPredecessor) {

		this.checkIfProxy(potentialPredecessor);
		if (potentialPredecessor == null) {
			NullPointerException e = new NullPointerException(
					"Reference to potential predecessor may not be null!");
			this.logger.error("Null pointer", e);
			throw e;
		}

		// if the local node did not have a predecessor reference before
		// or if the potential predecessor is closer to this local node,
		// replace the predecessor reference
		if (this.predecessor == null
				|| potentialPredecessor.getNodeID().isInInterval(
						this.predecessor.getNodeID(), this.localID)) {

			if (this.logger.isEnabledFor(INFO)) {
				this.logger
						.info("Setting a new predecessor reference: New reference is "
								+ potentialPredecessor
								+ ", old reference was "
								+ (this.predecessor == null ? "null"
										: this.predecessor));
			}

			// replace predecessor reference
			this.setPredecessor(potentialPredecessor);

			/*
			 * If a new predecessor, better than the old one has arrived, we
			 * have to copy the entries, that are relevant for this new
			 * predecessor. This has to be done by the predecessor itself, NOT
			 * here. 18.06.2007. sven
			 */
			// final Set<Entry> entries = this.entries.getEntriesInInterval(
			// this.predecessor.nodeID, this.localID);
			// this.localChord.getAsyncExecutor().execute(new Runnable() {
			// public void run() {
			// try {
			// for (Entry entryToInsert : entries) {
			// getPredecessor().insertEntry(entryToInsert);
			// }
			// } catch (CommunicationException e) {
			// }
			// }
			// });
		}

		// add reference
		this.addReference(potentialPredecessor);

	}

	/**
	 * Determines the first i entries in the finger table.
	 * 
	 * @param i
	 * @return The first (i+1) entries of finger table. If there are fewer then
	 *         i+1 entries only these are returned.
	 */
	public List<Node> getFirstFingerTableEntries(int i) {
		return this.fingerTable.getFirstFingerTableEntries(i);
	}

	/**
	 * Added by sven on 21.03.2006. This data strucutre is supposed to work with
	 * remote references therefore it must be instances of Proxy. This method is
	 * used in every method that adds a new reference to this to check that it
	 * is an instance of Proxy. -> TODO: Consider to change type of all Nodes
	 * within this data structure to type Proxy!!!!
	 * 
	 * @param node
	 * @throws RuntimeException
	 */
	private void checkIfProxy(Node node) {
		if (!(node instanceof Proxy)) {
			String msg = "Trying to use local node " + node
					+ " with references. This is not possible."
					+ "If you see this Exception contact the developers!";
			RuntimeException e = new RuntimeException(msg);
			this.logger.fatal(msg, e);
			throw e;
		}
	}

}

⌨️ 快捷键说明

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