From 41fb630515c721e27a9b70812bc350056a6d1588 Mon Sep 17 00:00:00 2001 From: Joshua Kissoon Date: Sat, 26 Apr 2014 22:09:45 +0530 Subject: [PATCH] Content Lookup Operation Update Before the content lookup operation used to lookup a specified set of nodes then return the latest content; a short review of the paper showed that we only lookup until we find the Value then exit as soon as we do. Made the updates to the code. --- src/kademlia/Kademlia.java | 22 +++------- .../operation/ContentLookupOperation.java | 42 +++++++++---------- src/kademlia/tests/ContentSendingTest.java | 13 +++--- src/kademlia/tests/ContentUpdatingTest.java | 23 ++++------ src/kademlia/tests/RefreshOperationTest.java | 6 +-- src/kademlia/tests/SaveStateTest2.java | 15 ++----- 6 files changed, 45 insertions(+), 76 deletions(-) diff --git a/src/kademlia/Kademlia.java b/src/kademlia/Kademlia.java index ff5fdcd..1eac5f2 100644 --- a/src/kademlia/Kademlia.java +++ b/src/kademlia/Kademlia.java @@ -8,8 +8,6 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.net.InetAddress; -import java.util.ArrayList; -import java.util.List; import java.util.NoSuchElementException; import java.util.Timer; import java.util.TimerTask; @@ -20,6 +18,7 @@ import kademlia.core.KadServer; import kademlia.dht.DHT; import kademlia.dht.KadContent; import kademlia.dht.StorageEntry; +import kademlia.exceptions.ContentNotFoundException; import kademlia.exceptions.RoutingException; import kademlia.message.MessageFactory; import kademlia.node.Node; @@ -266,33 +265,24 @@ public class Kademlia * Get some content stored on the DHT * The content returned is a JSON String in byte format; this string is parsed into a class * - * @param param The parameters used to search for the content - * @param numNodesToQuery How many nodes should we query to get this content. We return all content on these nodes. + * @param param The parameters used to search for the content * * @return DHTContent The content * * @throws java.io.IOException */ - public List get(GetParameter param, int numNodesToQuery) throws NoSuchElementException, IOException + public StorageEntry get(GetParameter param) throws NoSuchElementException, IOException, ContentNotFoundException { - List contentFound = new ArrayList<>();; if (this.dht.contains(param)) { /* If the content exist in our own DHT, then return it. */ - contentFound.add(this.dht.get(param)); - } - - if (contentFound.size() == numNodesToQuery) - { - return contentFound; + return this.dht.get(param); } /* Seems like it doesn't exist in our DHT, get it from other Nodes */ - ContentLookupOperation clo = new ContentLookupOperation(server, localNode, param, numNodesToQuery, this.config); + ContentLookupOperation clo = new ContentLookupOperation(server, localNode, param, this.config); clo.execute(); - contentFound = clo.getContentFound(); - - return contentFound; + return clo.getContentFound(); } /** diff --git a/src/kademlia/operation/ContentLookupOperation.java b/src/kademlia/operation/ContentLookupOperation.java index f4e51d8..f7eac5b 100644 --- a/src/kademlia/operation/ContentLookupOperation.java +++ b/src/kademlia/operation/ContentLookupOperation.java @@ -14,6 +14,7 @@ import kademlia.dht.GetParameter; import kademlia.core.KadConfiguration; import kademlia.core.KadServer; import kademlia.dht.StorageEntry; +import kademlia.exceptions.ContentNotFoundException; import kademlia.exceptions.RoutingException; import kademlia.exceptions.UnknownMessageException; import kademlia.message.ContentLookupMessage; @@ -40,14 +41,12 @@ public class ContentLookupOperation implements Operation, Receiver private final KadServer server; private final Node localNode; - private final GetParameter params; - private final List contentFound; - private final int numNodesToQuery; + private StorageEntry contentFound = null; private final KadConfiguration config; private final ContentLookupMessage lookupMessage; - private boolean contentsFound; + private boolean isContentFound; private final SortedMap nodes; /* Tracks messages in transit and awaiting reply */ @@ -58,27 +57,23 @@ public class ContentLookupOperation implements Operation, Receiver { - contentFound = new ArrayList<>(); messagesTransiting = new HashMap<>(); - contentsFound = false; + isContentFound = false; } /** * @param server * @param localNode - * @param params The parameters to search for the content which we need to find - * @param numNodesToQuery The number of nodes to query to get this content. We return the content among these nodes. + * @param params The parameters to search for the content which we need to find * @param config */ - public ContentLookupOperation(KadServer server, Node localNode, GetParameter params, int numNodesToQuery, KadConfiguration config) + public ContentLookupOperation(KadServer server, Node localNode, GetParameter params, KadConfiguration config) { /* Construct our lookup message */ this.lookupMessage = new ContentLookupMessage(localNode, params); this.server = server; this.localNode = localNode; - this.params = params; - this.numNodesToQuery = numNodesToQuery; this.config = config; /** @@ -111,7 +106,7 @@ public class ContentLookupOperation implements Operation, Receiver int timeInterval = 100; // We re-check every 300 milliseconds while (totalTimeWaited < this.config.operationTimeout()) { - if (!this.askNodesorFinish() && !contentsFound) + if (!this.askNodesorFinish() && !isContentFound) { wait(timeInterval); totalTimeWaited += timeInterval; @@ -230,7 +225,7 @@ public class ContentLookupOperation implements Operation, Receiver @Override public synchronized void receive(Message incoming, int comm) throws IOException, RoutingException { - if (this.contentsFound) + if (this.isContentFound) { return; } @@ -246,14 +241,8 @@ public class ContentLookupOperation implements Operation, Receiver /* Get the Content and check if it satisfies the required parameters */ StorageEntry content = msg.getContent(); System.out.println("Content Received: " + content); - - this.contentFound.add(content); - - if (this.contentFound.size() == this.numNodesToQuery) - { - /* We've got all the content required, let's stop the loopup operation */ - this.contentsFound = true; - } + this.contentFound = content; + this.isContentFound = true; } else { @@ -305,8 +294,15 @@ public class ContentLookupOperation implements Operation, Receiver /** * @return The list of all content found during the lookup operation */ - public List getContentFound() + public StorageEntry getContentFound() throws ContentNotFoundException { - return this.contentFound; + if (this.isContentFound) + { + return this.contentFound; + } + else + { + throw new ContentNotFoundException("No Value was found for the given key."); + } } } diff --git a/src/kademlia/tests/ContentSendingTest.java b/src/kademlia/tests/ContentSendingTest.java index 2bd17c2..901b22c 100644 --- a/src/kademlia/tests/ContentSendingTest.java +++ b/src/kademlia/tests/ContentSendingTest.java @@ -1,10 +1,10 @@ package kademlia.tests; import java.io.IOException; -import java.util.List; import kademlia.dht.GetParameter; import kademlia.Kademlia; import kademlia.dht.StorageEntry; +import kademlia.exceptions.ContentNotFoundException; import kademlia.node.NodeId; /** @@ -40,15 +40,12 @@ public class ContentSendingTest GetParameter gp = new GetParameter(c.getKey(), DHTContentImpl.TYPE); gp.setOwnerId(c.getOwnerId()); System.out.println("Get Parameter: " + gp); - List conte = kad2.get(gp, 4); - for (StorageEntry cc : conte) - { - System.out.println("Content Found: " + new DHTContentImpl().fromBytes(cc.getContent().getBytes())); - System.out.println("Content Metadata: " + cc.getContentMetadata()); - } + StorageEntry conte = kad2.get(gp); + System.out.println("Content Found: " + new DHTContentImpl().fromBytes(conte.getContent().getBytes())); + System.out.println("Content Metadata: " + conte.getContentMetadata()); } - catch (IOException e) + catch (IOException | ContentNotFoundException e) { e.printStackTrace(); } diff --git a/src/kademlia/tests/ContentUpdatingTest.java b/src/kademlia/tests/ContentUpdatingTest.java index 3e813c9..83b5834 100644 --- a/src/kademlia/tests/ContentUpdatingTest.java +++ b/src/kademlia/tests/ContentUpdatingTest.java @@ -1,10 +1,10 @@ package kademlia.tests; import java.io.IOException; -import java.util.List; import kademlia.dht.GetParameter; import kademlia.Kademlia; import kademlia.dht.StorageEntry; +import kademlia.exceptions.ContentNotFoundException; import kademlia.node.NodeId; /** @@ -34,13 +34,11 @@ public class ContentUpdatingTest /* Lets retrieve the content */ System.out.println("Retrieving Content"); GetParameter gp = new GetParameter(c.getKey(), DHTContentImpl.TYPE, c.getOwnerId()); + System.out.println("Get Parameter: " + gp); - List conte = kad2.get(gp, 4); - for (StorageEntry cc : conte) - { - System.out.println("Content Found: " + new DHTContentImpl().fromBytes(cc.getContent().getBytes())); - System.out.println("Content Metadata: " + cc.getContentMetadata()); - } + StorageEntry conte = kad2.get(gp); + System.out.println("Content Found: " + new DHTContentImpl().fromBytes(conte.getContent().getBytes())); + System.out.println("Content Metadata: " + conte.getContentMetadata()); /* Lets update the content and put it again */ c.setData("Some New Data"); @@ -48,15 +46,12 @@ public class ContentUpdatingTest /* Lets retrieve the content */ System.out.println("Retrieving Content Again"); - conte = kad2.get(gp, 4); - for (StorageEntry cc : conte) - { - System.out.println("Content Found: " + new DHTContentImpl().fromBytes(cc.getContent().getBytes())); - System.out.println("Content Metadata: " + cc.getContentMetadata()); - } + conte = kad2.get(gp); + System.out.println("Content Found: " + new DHTContentImpl().fromBytes(conte.getContent().getBytes())); + System.out.println("Content Metadata: " + conte.getContentMetadata()); } - catch (IOException e) + catch (IOException | ContentNotFoundException e) { e.printStackTrace(); } diff --git a/src/kademlia/tests/RefreshOperationTest.java b/src/kademlia/tests/RefreshOperationTest.java index 9dd2331..8a48f8c 100644 --- a/src/kademlia/tests/RefreshOperationTest.java +++ b/src/kademlia/tests/RefreshOperationTest.java @@ -1,10 +1,10 @@ package kademlia.tests; import java.io.IOException; -import java.util.List; import kademlia.dht.GetParameter; import kademlia.Kademlia; import kademlia.dht.StorageEntry; +import kademlia.exceptions.ContentNotFoundException; import kademlia.node.NodeId; /** @@ -33,11 +33,11 @@ public class RefreshOperationTest GetParameter gp = new GetParameter(c.getKey(), DHTContentImpl.TYPE); gp.setType(DHTContentImpl.TYPE); gp.setOwnerId(c.getOwnerId()); - List conte = kad2.get(gp, 1); + StorageEntry conte = kad2.get(gp); kad2.refresh(); } - catch (IOException e) + catch (IOException | ContentNotFoundException e) { e.printStackTrace(); } diff --git a/src/kademlia/tests/SaveStateTest2.java b/src/kademlia/tests/SaveStateTest2.java index db77155..c6fdbd5 100644 --- a/src/kademlia/tests/SaveStateTest2.java +++ b/src/kademlia/tests/SaveStateTest2.java @@ -1,6 +1,5 @@ package kademlia.tests; -import java.util.List; import kademlia.Kademlia; import kademlia.dht.GetParameter; import kademlia.dht.StorageEntry; @@ -53,17 +52,9 @@ public class SaveStateTest2 /* Trying to get a content stored on the restored node */ GetParameter gp = new GetParameter(c.getKey(), kad2.getOwnerId(), c.getType()); - List content = kad2.get(gp, 1); - - if (!content.isEmpty()) - { - DHTContentImpl cc = new DHTContentImpl().fromBytes(content.get(0).getContent().getBytes()); - System.out.println("Content received: " + cc); - } - else - { - System.out.println("No Content found"); - } + StorageEntry content = kad2.get(gp); + DHTContentImpl cc = new DHTContentImpl().fromBytes(content.getContent().getBytes()); + System.out.println("Content received: " + cc); } catch (Exception e)