mirror of
https://github.com/ChronosX88/KademliaDHT.git
synced 2024-12-23 00:01:46 +00:00
Started working on the RefreshOperations
This commit is contained in:
parent
e4726b93f8
commit
acd7885dba
@ -80,9 +80,12 @@ is divided into following sections:
|
||||
</and>
|
||||
</condition>
|
||||
<condition property="do.archive">
|
||||
<not>
|
||||
<istrue value="${jar.archive.disabled}"/>
|
||||
</not>
|
||||
<or>
|
||||
<not>
|
||||
<istrue value="${jar.archive.disabled}"/>
|
||||
</not>
|
||||
<istrue value="${not.archive.disabled}"/>
|
||||
</or>
|
||||
</condition>
|
||||
<condition property="do.mkdist">
|
||||
<and>
|
||||
@ -1199,11 +1202,14 @@ is divided into following sections:
|
||||
</not>
|
||||
</and>
|
||||
</condition>
|
||||
<javadoc additionalparam="${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
|
||||
<condition else="" property="bug5101868workaround" value="*.java">
|
||||
<matches pattern="1\.[56](\..*)?" string="${java.version}"/>
|
||||
</condition>
|
||||
<javadoc additionalparam="-J-Dfile.encoding=${file.encoding} ${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
|
||||
<classpath>
|
||||
<path path="${javac.classpath}"/>
|
||||
</classpath>
|
||||
<fileset dir="${src.dir}" excludes="*.java,${excludes}" includes="${includes}">
|
||||
<fileset dir="${src.dir}" excludes="${bug5101868workaround},${excludes}" includes="${includes}">
|
||||
<filename name="**/*.java"/>
|
||||
</fileset>
|
||||
<fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
|
||||
@ -1277,7 +1283,7 @@ is divided into following sections:
|
||||
<mkdir dir="${build.test.results.dir}"/>
|
||||
</target>
|
||||
<target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
|
||||
<j2seproject3:test testincludes="**/*Test.java"/>
|
||||
<j2seproject3:test includes="${includes}" testincludes="**/*Test.java"/>
|
||||
</target>
|
||||
<target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
|
||||
<fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
|
||||
|
@ -4,5 +4,5 @@ build.xml.stylesheet.CRC32=8064a381@1.68.1.46
|
||||
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
||||
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
||||
nbproject/build-impl.xml.data.CRC32=7e563d6e
|
||||
nbproject/build-impl.xml.script.CRC32=5c6dd9f7
|
||||
nbproject/build-impl.xml.stylesheet.CRC32=5a01deb7@1.68.1.46
|
||||
nbproject/build-impl.xml.script.CRC32=934ae712
|
||||
nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.74.1.48
|
||||
|
@ -1,8 +1,3 @@
|
||||
/**
|
||||
* @author Joshua Kissoon
|
||||
* @created 20140215
|
||||
* @desc This server handles sending and receiving messages
|
||||
*/
|
||||
package kademlia.core;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
@ -23,6 +18,11 @@ import kademlia.message.MessageFactory;
|
||||
import kademlia.node.Node;
|
||||
import kademlia.operation.Receiver;
|
||||
|
||||
/**
|
||||
* @author Joshua Kissoon
|
||||
* @created 20140215
|
||||
* @desc This server handles sending and receiving messages
|
||||
*/
|
||||
public class KadServer
|
||||
{
|
||||
|
||||
|
@ -16,7 +16,8 @@ import kademlia.node.NodeId;
|
||||
import kademlia.operation.ConnectOperation;
|
||||
import kademlia.operation.ContentLookupOperation;
|
||||
import kademlia.operation.Operation;
|
||||
import kademlia.operation.RefreshOperation;
|
||||
import kademlia.operation.BucketRefreshOperation;
|
||||
import kademlia.operation.KadRefreshOperation;
|
||||
import kademlia.operation.StoreOperation;
|
||||
|
||||
/**
|
||||
@ -79,7 +80,7 @@ public class Kademlia
|
||||
try
|
||||
{
|
||||
/* Runs a RefreshOperation to refresh K-Buckets and stored content */
|
||||
new RefreshOperation(server, localNode).execute();
|
||||
new BucketRefreshOperation(server, localNode).execute();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
@ -174,6 +175,16 @@ public class Kademlia
|
||||
return contentFound;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow the user of the System to call refresh even out of the normal Kad refresh timing
|
||||
*
|
||||
* @throws java.io.IOException
|
||||
*/
|
||||
public void refresh() throws IOException
|
||||
{
|
||||
new KadRefreshOperation(server, localNode).execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return String The ID of the owner of this local network
|
||||
*/
|
||||
|
@ -42,11 +42,16 @@ public class NodeId implements Streamable
|
||||
new Random().nextBytes(keyBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the NodeId from a given byte[]
|
||||
*
|
||||
* @param bytes
|
||||
*/
|
||||
public NodeId(byte[] bytes)
|
||||
{
|
||||
if (bytes.length != ID_LENGTH / 8)
|
||||
{
|
||||
throw new IllegalArgumentException("Specified Data need to be " + (ID_LENGTH / 8) + " characters long.");
|
||||
throw new IllegalArgumentException("Specified Data need to be " + (ID_LENGTH / 8) + " characters long. Data Given: '" + new String(bytes) + "'");
|
||||
}
|
||||
this.keyBytes = bytes;
|
||||
}
|
||||
|
@ -1,23 +1,25 @@
|
||||
package kademlia.operation;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import kademlia.core.KadServer;
|
||||
import kademlia.node.Node;
|
||||
import kademlia.node.NodeId;
|
||||
|
||||
/**
|
||||
* At each time interval t, nodes need to refresh their K-Buckets and their Data Storage
|
||||
* This Operation will manage refreshing the K-Buckets and data storage
|
||||
* At each time interval t, nodes need to refresh their K-Buckets
|
||||
* This operation takes care of refreshing this node's K-Buckets
|
||||
*
|
||||
* @author Joshua Kissoon
|
||||
* @created 20140224
|
||||
*/
|
||||
public class RefreshOperation implements Operation
|
||||
public class BucketRefreshOperation implements Operation
|
||||
{
|
||||
|
||||
private final KadServer server;
|
||||
private final Node localNode;
|
||||
|
||||
public RefreshOperation(KadServer server, Node localNode)
|
||||
public BucketRefreshOperation(KadServer server, Node localNode)
|
||||
{
|
||||
this.server = server;
|
||||
this.localNode = localNode;
|
||||
@ -26,6 +28,17 @@ public class RefreshOperation implements Operation
|
||||
@Override
|
||||
public synchronized void execute() throws IOException
|
||||
{
|
||||
System.out.println("Bucket Refresh Operation Started");
|
||||
|
||||
/* Get a list of NodeIds for each distance from the LocalNode NodeId */
|
||||
List<NodeId> refreshIds = this.localNode.getRoutingTable().getRefreshList();
|
||||
|
||||
/* Test whether each nodeId in this list is a different distance from our current NID */
|
||||
for (NodeId nid : refreshIds)
|
||||
{
|
||||
System.out.println(nid.xor(localNode.getNodeId()).getFirstSetBitIndex());
|
||||
}
|
||||
|
||||
/* @todo Do a Node Lookup operation to refresh K-Buckets */
|
||||
new NodeLookupOperation(this.server, this.localNode, this.localNode.getNodeId()).execute();
|
||||
|
||||
@ -34,9 +47,5 @@ public class RefreshOperation implements Operation
|
||||
* This is better than asking closest nodes for data,
|
||||
* since the data may not always come from the closest nodes
|
||||
*/
|
||||
/**
|
||||
* @todo Delete any content on this node that this node is not one of the K-Closest nodes to
|
||||
* @todo Delete any expired content
|
||||
*/
|
||||
}
|
||||
}
|
19
src/kademlia/operation/ContentRefreshOperation.java
Normal file
19
src/kademlia/operation/ContentRefreshOperation.java
Normal file
@ -0,0 +1,19 @@
|
||||
package kademlia.operation;
|
||||
|
||||
/**
|
||||
* Refresh the data on this node by sending the data to the K-Closest nodes to the data
|
||||
*
|
||||
* @author Joshua Kissoon
|
||||
* @since 20140306
|
||||
*/
|
||||
public class ContentRefreshOperation
|
||||
{
|
||||
|
||||
public void execute()
|
||||
{
|
||||
/**
|
||||
* @todo Delete any content on this node that this node is not one of the K-Closest nodes to
|
||||
* @todo Delete any expired content
|
||||
*/
|
||||
}
|
||||
}
|
33
src/kademlia/operation/KadRefreshOperation.java
Normal file
33
src/kademlia/operation/KadRefreshOperation.java
Normal file
@ -0,0 +1,33 @@
|
||||
package kademlia.operation;
|
||||
|
||||
import java.io.IOException;
|
||||
import kademlia.core.KadServer;
|
||||
import kademlia.node.Node;
|
||||
|
||||
/**
|
||||
* An operation that handles refreshing the entire Kademlia Systems including buckets and content
|
||||
*
|
||||
* @author Joshua Kissoon
|
||||
* @since 20140306
|
||||
*/
|
||||
public class KadRefreshOperation implements Operation
|
||||
{
|
||||
|
||||
private final KadServer server;
|
||||
private final Node localNode;
|
||||
|
||||
public KadRefreshOperation(KadServer server, Node localNode)
|
||||
{
|
||||
this.server = server;
|
||||
this.localNode = localNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws IOException
|
||||
{
|
||||
/* Run our BucketRefreshOperation to refresh buckets */
|
||||
new BucketRefreshOperation(server, localNode).execute();
|
||||
|
||||
/* After buckets have been refreshed, we refresh content */
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
package kademlia.routing;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.List;
|
||||
import kademlia.node.Node;
|
||||
import kademlia.node.NodeId;
|
||||
@ -73,7 +74,7 @@ public class RoutingTable
|
||||
* @param target The NodeId to find contacts close to
|
||||
* @param num The number of contacts to find
|
||||
*
|
||||
* @return List<Contact> A List of num contacts closest to target
|
||||
* @return List A List of contacts closest to target
|
||||
*/
|
||||
public List<Node> findClosest(NodeId target, int num)
|
||||
{
|
||||
@ -145,7 +146,10 @@ public class RoutingTable
|
||||
return closest;
|
||||
}
|
||||
|
||||
public List<Node> getAllNodes()
|
||||
/**
|
||||
* @return List A List of all Nodes in this RoutingTable
|
||||
*/
|
||||
public List getAllNodes()
|
||||
{
|
||||
List<Node> nodes = new ArrayList<>();
|
||||
|
||||
@ -157,6 +161,53 @@ public class RoutingTable
|
||||
return nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Each bucket need to be refreshed at every time interval t.
|
||||
* Here we return an identifier in each bucket's range;
|
||||
* this identifier will then be used to look for nodes closest to this identifier
|
||||
* allowing the bucket to be refreshed.
|
||||
*
|
||||
* The first bucket containing only the local node is skipped.
|
||||
*
|
||||
* @return List A list of NodeIds for each distance (1 - NodeId.ID_LENGTH) from the LocalNode NodeId
|
||||
*/
|
||||
public List<NodeId> getRefreshList()
|
||||
{
|
||||
List<NodeId> refreshList = new ArrayList<>(NodeId.ID_LENGTH);
|
||||
|
||||
for (int i = 1; i < NodeId.ID_LENGTH; i++)
|
||||
{
|
||||
/* Construct a NodeId that is i bits away from the current node Id */
|
||||
System.out.println("\nGenerating a new NodeId ");
|
||||
BitSet temp = new BitSet(NodeId.ID_LENGTH);
|
||||
|
||||
/* Fill the first i parts with 1 */
|
||||
for (int j = 0; j < i; j++)
|
||||
{
|
||||
System.out.println("Got here 1 - j: " + j);
|
||||
temp.set(j);
|
||||
}
|
||||
|
||||
/* Fill the last parts with 0 */
|
||||
for (int j = i; j < NodeId.ID_LENGTH; j++)
|
||||
{
|
||||
System.out.println("Got here 2 - j: " + j);
|
||||
temp.set(j, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* LocalNode NodeId xor the Bits we generated will give a new NodeId
|
||||
* i distance away from our LocalNode NodeId, we add this to our refreshList
|
||||
*/
|
||||
System.out.println("Bits: " + temp);
|
||||
NodeId nid = this.localNode.getNodeId().xor(new NodeId(temp.toByteArray()));
|
||||
System.out.println("NodeId: " + nid);
|
||||
refreshList.add(nid);
|
||||
}
|
||||
|
||||
return refreshList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
|
45
src/kademlia/tests/RefreshOperationTest.java
Normal file
45
src/kademlia/tests/RefreshOperationTest.java
Normal file
@ -0,0 +1,45 @@
|
||||
package kademlia.tests;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import kademlia.core.GetParameter;
|
||||
import kademlia.core.Kademlia;
|
||||
import kademlia.dht.KadContent;
|
||||
import kademlia.node.NodeId;
|
||||
|
||||
/**
|
||||
* Testing sending and receiving content between 2 Nodes on a network
|
||||
*
|
||||
* @author Joshua Kissoon
|
||||
* @since 20140224
|
||||
*/
|
||||
public class RefreshOperationTest
|
||||
{
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
/* Setting up 2 Kad networks */
|
||||
Kademlia kad1 = new Kademlia("JoshuaK", new NodeId("ASF45678947584567467"), 7574);
|
||||
Kademlia kad2 = new Kademlia("Crystal", new NodeId("ASERTKJDHGVHERJHGFLK"), 7572);
|
||||
kad2.connect(kad1.getNode());
|
||||
|
||||
/* Lets create the content and share it */
|
||||
DHTContentImpl c = new DHTContentImpl(kad2.getOwnerId(), "Some Data");
|
||||
kad2.put(c);
|
||||
|
||||
/* Lets retrieve the content */
|
||||
GetParameter gp = new GetParameter(c.getKey());
|
||||
gp.setType(DHTContentImpl.TYPE);
|
||||
gp.setOwnerId(c.getOwnerId());
|
||||
List<KadContent> conte = kad2.get(gp, 1);
|
||||
|
||||
kad2.refresh();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user