mirror of
https://github.com/ChronosX88/KademliaDHT.git
synced 2024-11-22 02:02:21 +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>
|
</and>
|
||||||
</condition>
|
</condition>
|
||||||
<condition property="do.archive">
|
<condition property="do.archive">
|
||||||
<not>
|
<or>
|
||||||
<istrue value="${jar.archive.disabled}"/>
|
<not>
|
||||||
</not>
|
<istrue value="${jar.archive.disabled}"/>
|
||||||
|
</not>
|
||||||
|
<istrue value="${not.archive.disabled}"/>
|
||||||
|
</or>
|
||||||
</condition>
|
</condition>
|
||||||
<condition property="do.mkdist">
|
<condition property="do.mkdist">
|
||||||
<and>
|
<and>
|
||||||
@ -1199,11 +1202,14 @@ is divided into following sections:
|
|||||||
</not>
|
</not>
|
||||||
</and>
|
</and>
|
||||||
</condition>
|
</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>
|
<classpath>
|
||||||
<path path="${javac.classpath}"/>
|
<path path="${javac.classpath}"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
<fileset dir="${src.dir}" excludes="*.java,${excludes}" includes="${includes}">
|
<fileset dir="${src.dir}" excludes="${bug5101868workaround},${excludes}" includes="${includes}">
|
||||||
<filename name="**/*.java"/>
|
<filename name="**/*.java"/>
|
||||||
</fileset>
|
</fileset>
|
||||||
<fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
|
<fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
|
||||||
@ -1277,7 +1283,7 @@ is divided into following sections:
|
|||||||
<mkdir dir="${build.test.results.dir}"/>
|
<mkdir dir="${build.test.results.dir}"/>
|
||||||
</target>
|
</target>
|
||||||
<target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
|
<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>
|
||||||
<target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
|
<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>
|
<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.
|
# 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.
|
# 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.data.CRC32=7e563d6e
|
||||||
nbproject/build-impl.xml.script.CRC32=5c6dd9f7
|
nbproject/build-impl.xml.script.CRC32=934ae712
|
||||||
nbproject/build-impl.xml.stylesheet.CRC32=5a01deb7@1.68.1.46
|
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;
|
package kademlia.core;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
@ -23,6 +18,11 @@ import kademlia.message.MessageFactory;
|
|||||||
import kademlia.node.Node;
|
import kademlia.node.Node;
|
||||||
import kademlia.operation.Receiver;
|
import kademlia.operation.Receiver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Joshua Kissoon
|
||||||
|
* @created 20140215
|
||||||
|
* @desc This server handles sending and receiving messages
|
||||||
|
*/
|
||||||
public class KadServer
|
public class KadServer
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -16,7 +16,8 @@ import kademlia.node.NodeId;
|
|||||||
import kademlia.operation.ConnectOperation;
|
import kademlia.operation.ConnectOperation;
|
||||||
import kademlia.operation.ContentLookupOperation;
|
import kademlia.operation.ContentLookupOperation;
|
||||||
import kademlia.operation.Operation;
|
import kademlia.operation.Operation;
|
||||||
import kademlia.operation.RefreshOperation;
|
import kademlia.operation.BucketRefreshOperation;
|
||||||
|
import kademlia.operation.KadRefreshOperation;
|
||||||
import kademlia.operation.StoreOperation;
|
import kademlia.operation.StoreOperation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -79,7 +80,7 @@ public class Kademlia
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
/* Runs a RefreshOperation to refresh K-Buckets and stored content */
|
/* Runs a RefreshOperation to refresh K-Buckets and stored content */
|
||||||
new RefreshOperation(server, localNode).execute();
|
new BucketRefreshOperation(server, localNode).execute();
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
@ -174,6 +175,16 @@ public class Kademlia
|
|||||||
return contentFound;
|
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
|
* @return String The ID of the owner of this local network
|
||||||
*/
|
*/
|
||||||
|
@ -42,11 +42,16 @@ public class NodeId implements Streamable
|
|||||||
new Random().nextBytes(keyBytes);
|
new Random().nextBytes(keyBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate the NodeId from a given byte[]
|
||||||
|
*
|
||||||
|
* @param bytes
|
||||||
|
*/
|
||||||
public NodeId(byte[] bytes)
|
public NodeId(byte[] bytes)
|
||||||
{
|
{
|
||||||
if (bytes.length != ID_LENGTH / 8)
|
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;
|
this.keyBytes = bytes;
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,25 @@
|
|||||||
package kademlia.operation;
|
package kademlia.operation;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
import kademlia.core.KadServer;
|
import kademlia.core.KadServer;
|
||||||
import kademlia.node.Node;
|
import kademlia.node.Node;
|
||||||
|
import kademlia.node.NodeId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* At each time interval t, nodes need to refresh their K-Buckets and their Data Storage
|
* At each time interval t, nodes need to refresh their K-Buckets
|
||||||
* This Operation will manage refreshing the K-Buckets and data storage
|
* This operation takes care of refreshing this node's K-Buckets
|
||||||
*
|
*
|
||||||
* @author Joshua Kissoon
|
* @author Joshua Kissoon
|
||||||
* @created 20140224
|
* @created 20140224
|
||||||
*/
|
*/
|
||||||
public class RefreshOperation implements Operation
|
public class BucketRefreshOperation implements Operation
|
||||||
{
|
{
|
||||||
|
|
||||||
private final KadServer server;
|
private final KadServer server;
|
||||||
private final Node localNode;
|
private final Node localNode;
|
||||||
|
|
||||||
public RefreshOperation(KadServer server, Node localNode)
|
public BucketRefreshOperation(KadServer server, Node localNode)
|
||||||
{
|
{
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.localNode = localNode;
|
this.localNode = localNode;
|
||||||
@ -26,6 +28,17 @@ public class RefreshOperation implements Operation
|
|||||||
@Override
|
@Override
|
||||||
public synchronized void execute() throws IOException
|
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 */
|
/* @todo Do a Node Lookup operation to refresh K-Buckets */
|
||||||
new NodeLookupOperation(this.server, this.localNode, this.localNode.getNodeId()).execute();
|
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,
|
* This is better than asking closest nodes for data,
|
||||||
* since the data may not always come from the closest nodes
|
* 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;
|
package kademlia.routing;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.BitSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import kademlia.node.Node;
|
import kademlia.node.Node;
|
||||||
import kademlia.node.NodeId;
|
import kademlia.node.NodeId;
|
||||||
@ -73,7 +74,7 @@ public class RoutingTable
|
|||||||
* @param target The NodeId to find contacts close to
|
* @param target The NodeId to find contacts close to
|
||||||
* @param num The number of contacts to find
|
* @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)
|
public List<Node> findClosest(NodeId target, int num)
|
||||||
{
|
{
|
||||||
@ -145,7 +146,10 @@ public class RoutingTable
|
|||||||
return closest;
|
return closest;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Node> getAllNodes()
|
/**
|
||||||
|
* @return List A List of all Nodes in this RoutingTable
|
||||||
|
*/
|
||||||
|
public List getAllNodes()
|
||||||
{
|
{
|
||||||
List<Node> nodes = new ArrayList<>();
|
List<Node> nodes = new ArrayList<>();
|
||||||
|
|
||||||
@ -157,6 +161,53 @@ public class RoutingTable
|
|||||||
return nodes;
|
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
|
@Override
|
||||||
public String toString()
|
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