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.
This commit is contained in:
Joshua Kissoon 2014-04-26 22:09:45 +05:30
parent 4fab4320df
commit 41fb630515
6 changed files with 45 additions and 76 deletions

View File

@ -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<StorageEntry> 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();
}
/**

View File

@ -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<StorageEntry> 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<Node, Byte> 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<StorageEntry> 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.");
}
}
}

View File

@ -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<StorageEntry> 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();
}

View File

@ -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<StorageEntry> 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();
}

View File

@ -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<StorageEntry> conte = kad2.get(gp, 1);
StorageEntry conte = kad2.get(gp);
kad2.refresh();
}
catch (IOException e)
catch (IOException | ContentNotFoundException e)
{
e.printStackTrace();
}

View File

@ -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<StorageEntry> 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)