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

📄 references.java

📁 一个对等计算发生器
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************
 *                                                                         *
 *                              References.java                            *
 *                            -------------------                          *
 *   date                 : 16.08.2004                                     *
 *   copyright            : (C) 2004/2005 Distributed and                  *
 *								Mobile Systems Group                       *
 *                              Lehrstuhl fuer Praktische Informatik       *
 *                              Universitaet Bamberg                       *
 *                              http://www.lspi.wiai.uni-bamberg.de/       *
 *   email                : sven.kaffille@wiai.uni-bamberg.de              *
 *   						karsten.loesing@wiai.uni-bamberg.de            *
 *                                                                         *
 *                                                                         *
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   A copy of the license can be found in the license.txt file supplied   *
 *   with this software or at: http://www.gnu.org/copyleft/gpl.html        *
 *                                                                         *
 ***************************************************************************/
package de.uniba.wiai.lspi.chord.service.impl;

import java.util.List;

import de.uniba.wiai.lspi.chord.com.Node;
import de.uniba.wiai.lspi.chord.com.Proxy;
import de.uniba.wiai.lspi.chord.data.ID;
import de.uniba.wiai.lspi.util.logging.Logger;

/**
 * Stores all remote references of nodes the local node is connected to and
 * provides methods for querying and manipulating these references. Makes use of
 * one finger table, one successor list, and one predecessor reference.
 * 
 * @author Karsten Loesing
 * @version 1.0.1
 */
final class References {

	/**
	 * Object logger.
	 */
	private Logger logger;

	/**
	 * This node's finger table.
	 */
	private FingerTable fingerTable = null;

	/**
	 * This node's successor list
	 */
	private SuccessorList successorList = null;

	/**
	 * This node's predecessor.
	 */
	private Node predecessor = null;

	/**
	 * This node's local ID.
	 */
	private ID localID = null;

	/**
	 * Creates an References object which contains no references.
	 * 
	 * @param localID
	 *            ID of local node.
	 * @param numberOfEntriesInSuccessorList
	 *            Length of successor list to be created.
	 * @param entries
	 *            Reference on this nodes' entries which is passed to creation
	 *            of the successor list.
	 * @throws NullPointerException
	 *             If either of the parameters is <code>null</code>.
	 * @throws IllegalArgumentException
	 *             If number of entries in successor list is negative.
	 */
	References(ID localID, int numberOfEntriesInSuccessorList, Entries entries) {

		if (localID == null || entries == null) {
			throw new NullPointerException(
					"Neither parameter of constructor may be null!");
		}

		if (numberOfEntriesInSuccessorList < 0)
			throw new IllegalArgumentException(
					"Number of entries in successor list cannot be negative!");

		this.logger = Logger.getLogger(References.class.getName() + "."
				+ localID);
		this.logger.debug("Logger initialized.");

		// store node id
		this.localID = localID;

		// create empty finger table and successor list
		this.fingerTable = new FingerTable(localID, this);
		this.successorList = new SuccessorList(localID,
				numberOfEntriesInSuccessorList, this, entries);
	}

	/**
	 * Determines the closest preceding node for the given ID based on finger
	 * table, successor list, and predecessor, but without testing the node's
	 * liveliness.
	 * 
	 * @param key
	 *            ID to find closest preceding node for.
	 * @throws NullPointerException
	 *             If ID is <code>null</code>.
	 * @return Reference on closest preceding node.
	 */
	final synchronized Node getClosestPrecedingNode(ID key) {

		if (key == null) {
			NullPointerException e = new NullPointerException(
					"ID may not be null!");
			this.logger.error("Null pointer", e);
			throw e;
		}

		// determine closest preceding reference of finger table
		Node closestNodeFT = this.fingerTable.getClosestPrecedingNode(key);

		// determine closest preceding reference of successor list
		Node closestNodeSL = this.successorList.getClosestPrecedingNode(key);

		// predecessor is appropriate only if it precedes the given id
		Node predecessorIfAppropriate = null;
		if (this.predecessor != null && key.isInInterval(this.predecessor.nodeID, this.localID)) {
			predecessorIfAppropriate = this.predecessor;
		}

		// with three references which may be null, there are eight (8) cases we
		// have to enumerate...
		Node closestNode;
		if (closestNodeFT == null) {
			if (closestNodeSL == null) {
				if (predecessorIfAppropriate == null) {
					// no reference is appropriate
					closestNode = null;
				} else {
					// only predecessor is appropriate (case should not occur,
					// but anyway...
					closestNode = predecessorIfAppropriate;
				}
			} else {
				if (predecessorIfAppropriate == null) {
					// only reference of successor list is appropriate
					closestNode = closestNodeSL;
				} else {
					// either predecessor or reference of successor list is
					// appropriate; determine one of both
					if (predecessorIfAppropriate.nodeID.isInInterval(
							closestNodeSL.nodeID, key)) {
						closestNode = predecessorIfAppropriate;
					} else {
						closestNode = closestNodeSL;
					}
				}
			}
		} else {
			if (closestNodeSL == null) {
				if (predecessorIfAppropriate == null) {
					// only reference of finger table is appropriate
					closestNode = closestNodeFT;
				} else {
					// either predecessor or reference of finger table is
					// appropriate; determine one of both
					if (predecessorIfAppropriate.nodeID.isInInterval(
							closestNodeFT.nodeID, key)) {
						closestNode = predecessorIfAppropriate;
					} else {
						closestNode = closestNodeFT;
					}
				}
			} else {
				if (predecessorIfAppropriate == null) {
					// either reference of successor list or reference of finger
					// table is appropriate; determine one of both
					if (closestNodeSL.nodeID.isInInterval(closestNodeFT.nodeID,
							key)) {
						closestNode = closestNodeSL;
					} else {
						closestNode = closestNodeFT;
					}
				} else {
					// either of the three reference is appropriate; determine
					// first one of the references of successor list and finger
					// table is more appropriate and afterwards compare with
					// predecessor
					if (closestNodeSL.nodeID.isInInterval(closestNodeFT.nodeID,
							key)) {
						if (predecessorIfAppropriate.nodeID.isInInterval(
								closestNodeSL.nodeID, key)) {
							closestNode = predecessorIfAppropriate;
						} else {
							closestNode = closestNodeSL;
						}
					} else {
						if (predecessorIfAppropriate.nodeID.isInInterval(
								closestNodeFT.nodeID, key)) {
							closestNode = predecessorIfAppropriate;
						} else {
							closestNode = closestNodeFT;
						}
					}
				}
			}
		}

		this.logger.debug("Closest preceding node of ID "
				+ key
				+ " at node "
				+ this.localID.toString()
				+ " is "
				+ (closestNode == null ? "null" : "" + closestNode.nodeID)
				+ " with closestNodeFT="
				+ (closestNodeFT == null ? "null" : "" + closestNodeFT.nodeID)
				+ " and closestNodeSL="
				+ (closestNodeSL == null ? "null" : "" + closestNodeSL.nodeID)
				+ " and predecessor (only if it precedes given ID)="
				+ (predecessorIfAppropriate == null ? "null" : ""
						+ predecessorIfAppropriate.nodeID));

		return closestNode;
	}

	/**
	 * Adds the given node reference to the finger table and successor list, if
	 * appropriate. The reference is NOT set as predecessor, even if is closer
	 * to this node. Therefore use {@link #addReferenceAsPredecessor(Node)}.
	 * 
	 * @param newReference
	 *            Reference to be added to the local data structures.
	 * @throws NullPointerException
	 *             If the given reference is null.
	 */
	final synchronized void addReference(Node newReference) {

		// check parameters
		this.checkIfProxy(newReference); 
		if (newReference == null) {
			NullPointerException e = new NullPointerException(
					"Node reference to be added must not be null!");
			this.logger.error("Null pointer", e);
			throw e;
		}

		if (newReference.nodeID.equals(this.localID)) {
			this.logger.info("Reference on myself was not added");
			return;
		}

		this.fingerTable.addReference(newReference);
		this.successorList.addSuccessor(newReference);

		this.logger.info("Attempted to add reference "
				+ newReference.nodeID.toString()
				+ " to finger table and successor list. Whether it fit "
				+ "or not depends on those data structures.");
	}

⌨️ 快捷键说明

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