diff --git a/src/kademlia/routing/RoutingTable.java b/src/kademlia/routing/RoutingTable.java index f6c127b..5fa9c6b 100644 --- a/src/kademlia/routing/RoutingTable.java +++ b/src/kademlia/routing/RoutingTable.java @@ -84,14 +84,14 @@ public class RoutingTable /** * Find the closest set of contacts to a given NodeId * - * @param target The NodeId to find contacts close to - * @param num The number of contacts to find + * @param target The NodeId to find contacts close to + * @param numNodesRequired The number of contacts to find * * @return List A List of contacts closest to target */ - public final List findClosest(NodeId target, int num) + public final List findClosest(NodeId target, int numNodesRequired) { - List closest = new ArrayList<>(num); + List closest = new ArrayList<>(numNodesRequired); /* Get the bucket index to search for closest from */ int bucketIndex = this.getBucketId(target); @@ -99,7 +99,7 @@ public class RoutingTable /* Add the contacts from this bucket to the return contacts */ for (Node c : this.buckets[bucketIndex].getNodes()) { - if (closest.size() < num) + if (closest.size() < numNodesRequired) { closest.add(c); } @@ -109,48 +109,60 @@ public class RoutingTable } } - if (closest.size() >= num) + if (closest.size() >= numNodesRequired) { return closest; } - /* If we still need more nodes, we add from buckets on either side of the closest bucket */ - for (int i = 1; ((bucketIndex - i) >= 0 || (bucketIndex + i) < NodeId.ID_LENGTH); i++) + /** + * We still need more nodes + * Lets add from nodes closer to localNode since they are the ones that will be closer to the given nid + */ + for (int i = 1; (bucketIndex - i) >= 0; i++) { - /* Check the bucket on the left side */ - if (bucketIndex - i > 0) + for (Node c : this.buckets[bucketIndex - i].getNodes()) { - for (Node c : this.buckets[bucketIndex - i].getNodes()) + if (closest.size() < numNodesRequired) { - if (closest.size() < num) - { - closest.add(c); - } - else - { - break; - } + closest.add(c); } - } - - /* Check the bucket on the right side */ - if (bucketIndex + i < NodeId.ID_LENGTH) - { - for (Node c : this.buckets[bucketIndex + i].getNodes()) + else { - if (closest.size() < num) - { - closest.add(c); - } - else - { - break; - } + break; } } /* If we have enough contacts, then stop adding */ - if (closest.size() >= num) + if (closest.size() >= numNodesRequired) + { + break; + } + } + + if (closest.size() >= numNodesRequired) + { + return closest; + } + + /** + * We still need more nodes, add from nodes farther to localNode + */ + for (int i = 1; (bucketIndex + i) < NodeId.ID_LENGTH; i++) + { + for (Node c : this.buckets[bucketIndex + i].getNodes()) + { + if (closest.size() < numNodesRequired) + { + closest.add(c); + } + else + { + break; + } + } + + /* If we have enough contacts, then stop adding */ + if (closest.size() >= numNodesRequired) { break; } diff --git a/src/kademlia/tests/AutoRefreshOperationTest.java b/src/kademlia/tests/AutoRefreshOperationTest.java index 6ccf3e8..9d50052 100644 --- a/src/kademlia/tests/AutoRefreshOperationTest.java +++ b/src/kademlia/tests/AutoRefreshOperationTest.java @@ -20,11 +20,11 @@ public class AutoRefreshOperationTest try { /* Setting up 2 Kad networks */ - final Kademlia kad1 = new Kademlia("JoshuaK", new NodeId("ASF45678947584567463"), 12049); - final Kademlia kad2 = new Kademlia("Crystal", new NodeId("ASF45678947584567464"), 4585); - final Kademlia kad3 = new Kademlia("Shameer", new NodeId("ASF45678947584567465"), 8104); - final Kademlia kad4 = new Kademlia("Lokesh", new NodeId("ASF45678947584567466"), 8335); - final Kademlia kad5 = new Kademlia("Chandu", new NodeId("ASF45678947584567467"), 13345); + final Kademlia kad1 = new Kademlia("JoshuaK", new NodeId("ASF456789djem45674DH"), 12049); + final Kademlia kad2 = new Kademlia("Crystal", new NodeId("AJDHR678947584567464"), 4585); + final Kademlia kad3 = new Kademlia("Shameer", new NodeId("AS84k6789KRNS45KFJ8W"), 8104); + final Kademlia kad4 = new Kademlia("Lokesh.", new NodeId("ASF45678947A845674GG"), 8335); + final Kademlia kad5 = new Kademlia("Chandu.", new NodeId("AS84RUD894758456dyrj"), 13345); /* Connecting nodes */ System.out.println("Connecting Nodes"); @@ -33,10 +33,19 @@ public class AutoRefreshOperationTest kad4.bootstrap(kad2.getNode()); kad5.bootstrap(kad4.getNode()); - DHTContentImpl c = new DHTContentImpl(kad1.getOwnerId(), "Some Data"); - kad1.putLocally(c); + DHTContentImpl c = new DHTContentImpl(new NodeId("AS84k678947584567465"), kad1.getOwnerId()); + c.setData("Setting the data"); + + System.out.println("\n Content ID: " + c.getKey()); + System.out.println(kad1.getNode() + " Distance from content: " + kad1.getNode().getNodeId().getDistance(c.getKey())); + System.out.println(kad2.getNode() + " Distance from content: " + kad2.getNode().getNodeId().getDistance(c.getKey())); + System.out.println(kad3.getNode() + " Distance from content: " + kad3.getNode().getNodeId().getDistance(c.getKey())); + System.out.println(kad4.getNode() + " Distance from content: " + kad4.getNode().getNodeId().getDistance(c.getKey())); + System.out.println(kad5.getNode() + " Distance from content: " + kad5.getNode().getNodeId().getDistance(c.getKey())); System.out.println("\nSTORING CONTENT 1 locally on " + kad1.getOwnerId() + "\n\n\n\n"); + kad1.putLocally(c); + System.out.println(kad1); System.out.println(kad2); System.out.println(kad3); diff --git a/src/kademlia/tests/AutoRefreshOperationTest2.java b/src/kademlia/tests/AutoRefreshOperationTest2.java new file mode 100644 index 0000000..7d4f7a3 --- /dev/null +++ b/src/kademlia/tests/AutoRefreshOperationTest2.java @@ -0,0 +1,75 @@ +package kademlia.tests; + +import java.util.Timer; +import java.util.TimerTask; +import kademlia.core.Configuration; +import kademlia.core.Kademlia; +import kademlia.node.NodeId; + +/** + * Testing the Kademlia Auto Content and Node table refresh operations + * + * @author Joshua Kissoon + * @since 20140309 + */ +public class AutoRefreshOperationTest2 +{ + + public AutoRefreshOperationTest2() + { + try + { + /* Setting up 2 Kad networks */ + final Kademlia kad1 = new Kademlia("JoshuaK", new NodeId("ASF456789djem4567463"), 12049); + final Kademlia kad2 = new Kademlia("Crystal", new NodeId("AS84k678DJRW84567465"), 4585); + final Kademlia kad3 = new Kademlia("Shameer", new NodeId("AS84k67894758456746A"), 8104); + + /* Connecting nodes */ + System.out.println("Connecting Nodes"); + kad2.bootstrap(kad1.getNode()); + kad3.bootstrap(kad2.getNode()); + + DHTContentImpl c = new DHTContentImpl(new NodeId("AS84k678947584567465"), kad1.getOwnerId()); + c.setData("Setting the data"); + kad1.putLocally(c); + + + System.out.println("\n Content ID: " + c.getKey()); + System.out.println(kad1.getNode() + " Distance from content: " + kad1.getNode().getNodeId().getDistance(c.getKey())); + System.out.println(kad2.getNode() + " Distance from content: " + kad2.getNode().getNodeId().getDistance(c.getKey())); + System.out.println(kad3.getNode() + " Distance from content: " + kad3.getNode().getNodeId().getDistance(c.getKey())); + System.out.println("\nSTORING CONTENT 1 locally on " + kad1.getOwnerId() + "\n\n\n\n"); + + System.out.println(kad1); + System.out.println(kad2); + System.out.println(kad3); + + /* Print the node states every few minutes */ + Timer timer = new Timer(true); + timer.schedule( + new TimerTask() + { + @Override + public void run() + { + System.out.println(kad1); + System.out.println(kad2); + System.out.println(kad3); + } + }, + // Delay // Interval + Configuration.RESTORE_INTERVAL, Configuration.RESTORE_INTERVAL + ); + } + + catch (Exception e) + { + e.printStackTrace(); + } + } + + public static void main(String[] args) + { + new AutoRefreshOperationTest2(); + } +}