Route Length Computation

- Before we were doing this by just adding incrementing a value everytime we get a set of nodes as the reply of a FIND_NODE or FIND_VALUE RPC
-- This may be wrong since nodes the same distance away may reply and we'll still be incrementing for both
- Created a route length checker class to properly check route lengths

ContentLookupOperation
- Added the route length check to the CLO operation

Didn't add it to the NodeLookupOperation since I'm not sure we're using it anywhere... Though it can be useful there
This commit is contained in:
Joshua Kissoon 2014-05-10 21:17:44 +05:30
parent 799a4887dd
commit d242e0a13a
3 changed files with 105 additions and 9 deletions

View File

@ -24,6 +24,7 @@ import kademlia.message.Message;
import kademlia.message.NodeReplyMessage; import kademlia.message.NodeReplyMessage;
import kademlia.node.KeyComparator; import kademlia.node.KeyComparator;
import kademlia.node.Node; import kademlia.node.Node;
import kademlia.util.RouteLengthChecker;
/** /**
* Looks up a specified identifier and returns the value associated with it * Looks up a specified identifier and returns the value associated with it
@ -57,13 +58,12 @@ public class ContentLookupOperation implements Operation, Receiver
private final Comparator comparator; private final Comparator comparator;
/* Statistical information */ /* Statistical information */
private int routeLength; // Length of the route to find this content private RouteLengthChecker routeLengthChecker;
{ {
messagesTransiting = new HashMap<>(); messagesTransiting = new HashMap<>();
isContentFound = false; isContentFound = false;
routeLength = 1;
} }
/** /**
@ -105,7 +105,11 @@ public class ContentLookupOperation implements Operation, Receiver
* We add all nodes here instead of the K-Closest because there may be the case that the K-Closest are offline * We add all nodes here instead of the K-Closest because there may be the case that the K-Closest are offline
* - The operation takes care of looking at the K-Closest. * - The operation takes care of looking at the K-Closest.
*/ */
this.addNodes(this.localNode.getRoutingTable().getAllNodes()); List<Node> allNodes = this.localNode.getRoutingTable().getAllNodes();
this.addNodes(allNodes);
/* Also add the initial set of nodes to the routeLengthChecker */
this.routeLengthChecker.addInitialNodes(allNodes);
/** /**
* If we haven't found the requested amount of content as yet, * If we haven't found the requested amount of content as yet,
@ -254,9 +258,6 @@ public class ContentLookupOperation implements Operation, Receiver
} }
else else
{ {
/* Our hop length is increased */
this.routeLength++;
/* The reply received is a NodeReplyMessage with nodes closest to the content needed */ /* The reply received is a NodeReplyMessage with nodes closest to the content needed */
NodeReplyMessage msg = (NodeReplyMessage) incoming; NodeReplyMessage msg = (NodeReplyMessage) incoming;
@ -270,6 +271,9 @@ public class ContentLookupOperation implements Operation, Receiver
/* Remove this msg from messagesTransiting since it's completed now */ /* Remove this msg from messagesTransiting since it's completed now */
this.messagesTransiting.remove(comm); this.messagesTransiting.remove(comm);
/* Add the received nodes to the routeLengthChecker */
this.routeLengthChecker.addNodes(msg.getNodes(), origin);
/* Add the received nodes to our nodes list to query */ /* Add the received nodes to our nodes list to query */
this.addNodes(msg.getNodes()); this.addNodes(msg.getNodes());
this.askNodesorFinish(); this.askNodesorFinish();
@ -324,6 +328,6 @@ public class ContentLookupOperation implements Operation, Receiver
*/ */
public int routeLength() public int routeLength()
{ {
return this.routeLength; return this.routeLengthChecker.getRouteLength();
} }
} }

View File

@ -124,7 +124,7 @@ public class RoutingTable implements KadRoutingTable
* @return List A List of all Nodes in this RoutingTable * @return List A List of all Nodes in this RoutingTable
*/ */
@Override @Override
public synchronized final List getAllNodes() public synchronized final List<Node> getAllNodes()
{ {
List<Node> nodes = new ArrayList<>(); List<Node> nodes = new ArrayList<>();
@ -143,7 +143,7 @@ public class RoutingTable implements KadRoutingTable
* @return List A List of all Nodes in this RoutingTable * @return List A List of all Nodes in this RoutingTable
*/ */
@Override @Override
public final List getAllContacts() public final List<Contact> getAllContacts()
{ {
List<Contact> contacts = new ArrayList<>(); List<Contact> contacts = new ArrayList<>();

View File

@ -0,0 +1,92 @@
package kademlia.util;
import java.util.Collection;
import java.util.HashMap;
import kademlia.node.Node;
/**
* Class that helps compute the route length taken to complete an operation.
*
* Only used for routing operations - mainly the NodeLookup and ContentLookup Operations.
*
* Idea:
* - Add the original set of nodes with route length 0;
* - When we get a node reply with a set of nodes, we add those nodes and set the route length to their sender route length + 1
*
* @author Joshua Kissoon
* @since 20140510
*/
public class RouteLengthChecker
{
/* Store the nodes and their route length (RL) */
private final HashMap<Node, Integer> nodes;
/* Lets cache the max route length instead of having to go and search for it later */
private int maxRouteLength;
{
this.nodes = new HashMap<>();
this.maxRouteLength = 1;
}
/**
* Add the initial nodes in the routing operation
*
* @param initialNodes The set of initial nodes
*/
public void addInitialNodes(Collection<Node> initialNodes)
{
for (Node n : initialNodes)
{
this.nodes.put(n, 1);
}
}
/**
* Add any nodes that we get from a node reply.
*
* The route length of these nodes will be their sender + 1;
*
* @param inputSet The set of nodes we receive
* @param sender The node who send the set
*/
public void addNodes(Collection<Node> inputSet, Node sender)
{
if (!this.nodes.containsKey(sender))
{
return;
}
/* Get the route length of the input set - sender RL + 1 */
int inputSetRL = this.nodes.get(sender) + 1;
if (inputSetRL > this.maxRouteLength)
{
this.maxRouteLength = inputSetRL;
}
/* Add the nodes to our set */
for (Node n : inputSet)
{
/* We only add if the node is not already there... */
if (!this.nodes.containsKey(n))
{
this.nodes.put(n, inputSetRL);
}
}
}
/**
* Get the route length of the operation!
*
* It will be the max route length of all the nodes here.
*
* @return The route length
*/
public int getRouteLength()
{
return this.maxRouteLength;
}
}