From d242e0a13a4cd13db13af5717518eee57ef62420 Mon Sep 17 00:00:00 2001 From: Joshua Kissoon Date: Sat, 10 May 2014 21:17:44 +0530 Subject: [PATCH] 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 --- .../operation/ContentLookupOperation.java | 18 ++-- src/kademlia/routing/RoutingTable.java | 4 +- src/kademlia/util/RouteLengthChecker.java | 92 +++++++++++++++++++ 3 files changed, 105 insertions(+), 9 deletions(-) create mode 100644 src/kademlia/util/RouteLengthChecker.java diff --git a/src/kademlia/operation/ContentLookupOperation.java b/src/kademlia/operation/ContentLookupOperation.java index 18fcc57..2bf14f5 100644 --- a/src/kademlia/operation/ContentLookupOperation.java +++ b/src/kademlia/operation/ContentLookupOperation.java @@ -24,6 +24,7 @@ import kademlia.message.Message; import kademlia.message.NodeReplyMessage; import kademlia.node.KeyComparator; import kademlia.node.Node; +import kademlia.util.RouteLengthChecker; /** * 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; /* Statistical information */ - private int routeLength; // Length of the route to find this content + private RouteLengthChecker routeLengthChecker; { messagesTransiting = new HashMap<>(); 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 * - The operation takes care of looking at the K-Closest. */ - this.addNodes(this.localNode.getRoutingTable().getAllNodes()); + List 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, @@ -254,9 +258,6 @@ public class ContentLookupOperation implements Operation, Receiver } else { - /* Our hop length is increased */ - this.routeLength++; - /* The reply received is a NodeReplyMessage with nodes closest to the content needed */ NodeReplyMessage msg = (NodeReplyMessage) incoming; @@ -269,6 +270,9 @@ public class ContentLookupOperation implements Operation, Receiver /* Remove this msg from messagesTransiting since it's completed now */ 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 */ this.addNodes(msg.getNodes()); @@ -324,6 +328,6 @@ public class ContentLookupOperation implements Operation, Receiver */ public int routeLength() { - return this.routeLength; + return this.routeLengthChecker.getRouteLength(); } } diff --git a/src/kademlia/routing/RoutingTable.java b/src/kademlia/routing/RoutingTable.java index e2695a5..465d1e9 100644 --- a/src/kademlia/routing/RoutingTable.java +++ b/src/kademlia/routing/RoutingTable.java @@ -124,7 +124,7 @@ public class RoutingTable implements KadRoutingTable * @return List A List of all Nodes in this RoutingTable */ @Override - public synchronized final List getAllNodes() + public synchronized final List getAllNodes() { List nodes = new ArrayList<>(); @@ -143,7 +143,7 @@ public class RoutingTable implements KadRoutingTable * @return List A List of all Nodes in this RoutingTable */ @Override - public final List getAllContacts() + public final List getAllContacts() { List contacts = new ArrayList<>(); diff --git a/src/kademlia/util/RouteLengthChecker.java b/src/kademlia/util/RouteLengthChecker.java new file mode 100644 index 0000000..6fc7d27 --- /dev/null +++ b/src/kademlia/util/RouteLengthChecker.java @@ -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 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 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 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; + } +}