mirror of
https://github.com/ChronosX88/KademliaDHT.git
synced 2024-11-22 02:02:21 +00:00
Finish Bucket Refresh Operation :)
This commit is contained in:
parent
f91dea9e5f
commit
cabb5af742
@ -170,13 +170,13 @@ public class KadServer
|
|||||||
|
|
||||||
Message msg = messageFactory.createMessage(messCode, din);
|
Message msg = messageFactory.createMessage(messCode, din);
|
||||||
din.close();
|
din.close();
|
||||||
System.out.println(this.localNode.getNodeId() + " Message Received: [Comm: " + comm + "] " + msg);
|
//System.out.println(this.localNode.getNodeId() + " Message Received: [Comm: " + comm + "] " + msg);
|
||||||
|
|
||||||
/* Get a receiver for this message */
|
/* Get a receiver for this message */
|
||||||
Receiver receiver;
|
Receiver receiver;
|
||||||
if (this.receivers.containsKey(comm))
|
if (this.receivers.containsKey(comm))
|
||||||
{
|
{
|
||||||
System.out.println("Receiver found");
|
//System.out.println("Receiver found");
|
||||||
/* If there is a reciever in the receivers to handle this */
|
/* If there is a reciever in the receivers to handle this */
|
||||||
synchronized (this)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
|
@ -10,6 +10,7 @@ import java.io.DataOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.BitSet;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import kademlia.message.Streamable;
|
import kademlia.message.Streamable;
|
||||||
|
|
||||||
@ -126,14 +127,43 @@ public class NodeId implements Streamable
|
|||||||
/**
|
/**
|
||||||
* Generates a NodeId that is some distance away from this NodeId
|
* Generates a NodeId that is some distance away from this NodeId
|
||||||
*
|
*
|
||||||
* @param distance
|
* @param distance in number of bits
|
||||||
*
|
*
|
||||||
* @return NodeId The newly generated NodeId
|
* @return NodeId The newly generated NodeId
|
||||||
*/
|
*/
|
||||||
public NodeId generateNodeIdByDistance(int distance)
|
public NodeId generateNodeIdByDistance(int distance)
|
||||||
{
|
{
|
||||||
byte[] result = new byte[ID_LENGTH / 8];
|
byte[] result = new byte[ID_LENGTH / 8];
|
||||||
int emptyBytes = distance / 8;
|
|
||||||
|
/* Since distance = ID_LENGTH - prefixLength, we need to fill that amount with 0's */
|
||||||
|
int numByteZeroes = (ID_LENGTH - distance) / 8;
|
||||||
|
int numBitZeroes = 8 - (distance % 8);
|
||||||
|
|
||||||
|
/* Filling byte zeroes */
|
||||||
|
for (int i = 0; i < numByteZeroes; i++)
|
||||||
|
{
|
||||||
|
result[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Filling bit zeroes */
|
||||||
|
BitSet bits = new BitSet(8);
|
||||||
|
bits.set(0, 8);
|
||||||
|
|
||||||
|
for (int i = 0; i < numBitZeroes; i++)
|
||||||
|
{
|
||||||
|
/* Shift 1 zero into the start of the value */
|
||||||
|
bits.clear(i);
|
||||||
|
}
|
||||||
|
bits.flip(0, 8); // Flip the bits since they're in reverse order
|
||||||
|
result[numByteZeroes] = (byte) bits.toByteArray()[0];
|
||||||
|
|
||||||
|
/* Set the remaining bytes to Maximum value */
|
||||||
|
for (int i = numByteZeroes + 1; i < result.length; i++)
|
||||||
|
{
|
||||||
|
result[i] = Byte.MAX_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.xor(new NodeId(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
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;
|
import kademlia.node.NodeId;
|
||||||
@ -25,27 +24,28 @@ public class BucketRefreshOperation implements Operation
|
|||||||
this.localNode = localNode;
|
this.localNode = localNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Each bucket need to be refreshed at every time interval t.
|
||||||
|
* Find an identifier in each bucket's range, use it to look for nodes closest to this identifier
|
||||||
|
* allowing the bucket to be refreshed.
|
||||||
|
*
|
||||||
|
* Then Do a NodeLookupOperation for each of the generated NodeIds,
|
||||||
|
* This will find the K-Closest nodes to that ID, and update the necessary K-Bucket
|
||||||
|
*
|
||||||
|
* @throws java.io.IOException
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public synchronized void execute() throws IOException
|
public synchronized void execute() throws IOException
|
||||||
{
|
{
|
||||||
System.out.println("Bucket Refresh Operation Started");
|
for (int i = 1; i < NodeId.ID_LENGTH; i++)
|
||||||
|
|
||||||
/* 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(localNode.getNodeId().getDistance(nid));
|
/* Construct a NodeId that is i bits away from the current node Id */
|
||||||
|
NodeId current = this.localNode.getNodeId().generateNodeIdByDistance(i);
|
||||||
|
|
||||||
|
// System.out.println("Distance: " + localNode.getNodeId().getDistance(current) + " - ID: " + current);
|
||||||
|
|
||||||
|
/* Run the Node Lookup Operation */
|
||||||
|
new NodeLookupOperation(this.server, this.localNode, this.localNode.getNodeId()).execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* @todo Do a Node Lookup operation to refresh K-Buckets */
|
|
||||||
new NodeLookupOperation(this.server, this.localNode, this.localNode.getNodeId()).execute();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @todo Send data in DHT to closest Nodes if they don't have it
|
|
||||||
* This is better than asking closest nodes for data,
|
|
||||||
* since the data may not always come from the closest nodes
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,15 +13,15 @@ import kademlia.node.NodeId;
|
|||||||
|
|
||||||
public class RoutingTable
|
public class RoutingTable
|
||||||
{
|
{
|
||||||
|
|
||||||
private final Node localNode; // The current node
|
private final Node localNode; // The current node
|
||||||
private final KadBucket[] buckets;
|
private final KadBucket[] buckets;
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
buckets = new KadBucket[NodeId.ID_LENGTH]; // 160 buckets; 1 for each level in the tree
|
buckets = new KadBucket[NodeId.ID_LENGTH]; // 160 buckets; 1 for each level in the tree
|
||||||
}
|
}
|
||||||
|
|
||||||
public RoutingTable(Node localNode)
|
public RoutingTable(Node localNode)
|
||||||
{
|
{
|
||||||
this.localNode = localNode;
|
this.localNode = localNode;
|
||||||
@ -43,7 +43,7 @@ public class RoutingTable
|
|||||||
/* bucketId is the distance between these nodes */
|
/* bucketId is the distance between these nodes */
|
||||||
int bucketId = this.localNode.getNodeId().getDistance(n.getNodeId()) - 1;
|
int bucketId = this.localNode.getNodeId().getDistance(n.getNodeId()) - 1;
|
||||||
|
|
||||||
System.out.println(this.localNode.getNodeId() + " Adding Node " + n.getNodeId() + " to bucket at depth: " + bucketId);
|
//System.out.println(this.localNode.getNodeId() + " Adding Node " + n.getNodeId() + " to bucket at depth: " + bucketId);
|
||||||
|
|
||||||
/* Put this contact to the bucket that stores contacts prefixLength distance away */
|
/* Put this contact to the bucket that stores contacts prefixLength distance away */
|
||||||
this.buckets[bucketId].insert(n);
|
this.buckets[bucketId].insert(n);
|
||||||
@ -93,7 +93,7 @@ public class RoutingTable
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (closest.size() >= num)
|
if (closest.size() >= num)
|
||||||
{
|
{
|
||||||
return closest;
|
return closest;
|
||||||
@ -140,7 +140,7 @@ public class RoutingTable
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return closest;
|
return closest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,62 +150,15 @@ public class RoutingTable
|
|||||||
public List getAllNodes()
|
public List getAllNodes()
|
||||||
{
|
{
|
||||||
List<Node> nodes = new ArrayList<>();
|
List<Node> nodes = new ArrayList<>();
|
||||||
|
|
||||||
for (KadBucket b : this.buckets)
|
for (KadBucket b : this.buckets)
|
||||||
{
|
{
|
||||||
nodes.addAll(b.getNodes());
|
nodes.addAll(b.getNodes());
|
||||||
}
|
}
|
||||||
|
|
||||||
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 bits = new BitSet(160);
|
|
||||||
|
|
||||||
/* Fill the first i parts with 1 */
|
|
||||||
for (int j = 0; j < i + 10; j++)
|
|
||||||
{
|
|
||||||
bits.set(j);
|
|
||||||
System.out.println("Got here 1 - j: " + j + "; bits: " + bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill the last parts with 0 */
|
|
||||||
for (int j = i; j < NodeId.ID_LENGTH; j++)
|
|
||||||
{
|
|
||||||
bits.clear(j);
|
|
||||||
System.out.println("Got here 2 - j: " + j + "; bits: " + bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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: " + bits.toByteArray());
|
|
||||||
NodeId nid = this.localNode.getNodeId().xor(new NodeId(bits.toByteArray()));
|
|
||||||
System.out.println("NodeId: " + nid);
|
|
||||||
refreshList.add(nid);
|
|
||||||
}
|
|
||||||
|
|
||||||
return refreshList;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
@ -225,8 +178,8 @@ public class RoutingTable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
sb.append("\nPrinting Routing Table Ended ******************** ");
|
sb.append("\nPrinting Routing Table Ended ******************** ");
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user