📄 references.java
字号:
/**
* 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);
this.logger.info("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.info("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() + "\n");
result.append(this.fingerTable.toString());
result.append(this.successorList.toString());
result.append("Predecessor: "
+ (this.getPredecessor() == null ? "null" : ""
+ this.getPredecessor().nodeID.toString()));
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.
* @uml.property name="predecessor"
*/
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.
* @uml.property name="predecessor"
*/
final synchronized void setPredecessor(Node potentialPredecessor) {
this.checkIfProxy(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;
}
if (!(potentialPredecessor.equals(this.predecessor))) {
Node formerPredecessor = this.predecessor;
this.predecessor = potentialPredecessor;
if (formerPredecessor != null) {
this.disconnectIfUnreferenced(formerPredecessor);
this.logger.info("Old predecessor " + formerPredecessor
+ " was replaced by " + potentialPredecessor);
} else {
this.logger.info("Predecessor reference set to "
+ potentialPredecessor + "; was null before.");
}
}
}
/**
* 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.nodeID.isInInterval(
this.predecessor.nodeID, this.localID)) {
this.logger
.info("Seting a new predecessor reference: New reference is "
+ potentialPredecessor
+ ", old reference was "
+ (this.predecessor == null ? "null"
: this.predecessor));
// replace predecessor reference
this.setPredecessor(potentialPredecessor);
}
// 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 + -