mirror of
https://github.com/ChronosX88/KademliaDHT.git
synced 2024-11-22 02:02:21 +00:00
Routing Table Contact Management
- Added last seen data to contact - Contacts are not sorted by lastSeen - Contact updating last seen time is handled Built a simulation to test the contact last seen updates
This commit is contained in:
parent
6253ad0ca6
commit
4fab4320df
@ -10,7 +10,7 @@ import java.io.File;
|
|||||||
public class DefaultConfiguration implements KadConfiguration
|
public class DefaultConfiguration implements KadConfiguration
|
||||||
{
|
{
|
||||||
|
|
||||||
private final static long RESTORE_INTERVAL = 10 * 1000; // Default at 1 hour
|
private final static long RESTORE_INTERVAL = 1000 * 1000; // Default at 1 hour
|
||||||
private final static long RESPONSE_TIMEOUT = 1500;
|
private final static long RESPONSE_TIMEOUT = 1500;
|
||||||
private final static long OPERATION_TIMEOUT = 3000;
|
private final static long OPERATION_TIMEOUT = 3000;
|
||||||
private final static int CONCURRENCY = 10;
|
private final static int CONCURRENCY = 10;
|
||||||
|
@ -7,23 +7,67 @@ import kademlia.node.Node;
|
|||||||
*
|
*
|
||||||
* Contacts are used instead of nodes because more information is needed than just the node information.
|
* Contacts are used instead of nodes because more information is needed than just the node information.
|
||||||
* - Information such as
|
* - Information such as
|
||||||
* -- Last alive time
|
* -- Last seen time
|
||||||
*
|
*
|
||||||
* @author Joshua Kissoon
|
* @author Joshua Kissoon
|
||||||
* @since 20140425
|
* @since 20140425
|
||||||
|
* @updated 20140426
|
||||||
*/
|
*/
|
||||||
public class Contact
|
public class Contact implements Comparable<Contact>
|
||||||
{
|
{
|
||||||
|
|
||||||
private final Node n;
|
private final Node n;
|
||||||
|
private long lastSeen;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a contact object
|
||||||
|
*
|
||||||
|
* @param n The node associated with this contact
|
||||||
|
*/
|
||||||
public Contact(Node n)
|
public Contact(Node n)
|
||||||
{
|
{
|
||||||
this.n = n;
|
this.n = n;
|
||||||
|
this.lastSeen = System.currentTimeMillis() / 1000L;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Node getNode()
|
public Node getNode()
|
||||||
{
|
{
|
||||||
return this.n;
|
return this.n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When a Node sees a contact a gain, the Node will want to update that it's seen recently,
|
||||||
|
* this method updates the last seen timestamp for this contact.
|
||||||
|
*/
|
||||||
|
public void setSeenNow()
|
||||||
|
{
|
||||||
|
this.lastSeen = System.currentTimeMillis() / 1000L;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When last was this contact seen?
|
||||||
|
*
|
||||||
|
* @return long The last time this contact was seen.
|
||||||
|
*/
|
||||||
|
public long lastSeen()
|
||||||
|
{
|
||||||
|
return this.lastSeen;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Contact c)
|
||||||
|
{
|
||||||
|
return c.getNode().equals(this.getNode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(Contact o)
|
||||||
|
{
|
||||||
|
if (this.getNode().equals(o.getNode()))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (this.lastSeen() > o.lastSeen()) ? 1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
34
src/kademlia/routing/ContactLastSeenComparator.java
Normal file
34
src/kademlia/routing/ContactLastSeenComparator.java
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package kademlia.routing;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Comparator to compare 2 contacts by their last seen time
|
||||||
|
*
|
||||||
|
* @author Joshua Kissoon
|
||||||
|
* @since 20140426
|
||||||
|
*/
|
||||||
|
public class ContactLastSeenComparator implements Comparator<Contact>
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare two contacts to determine their order in the Bucket,
|
||||||
|
* Contacts are ordered by their last seen timestamp.
|
||||||
|
*
|
||||||
|
* @param c1 Contact 1
|
||||||
|
* @param c2 Contact 2
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int compare(Contact c1, Contact c2)
|
||||||
|
{
|
||||||
|
if (c1.getNode().equals(c2.getNode()))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We may have 2 different contacts with same last seen values so we can't return 0 here */
|
||||||
|
return c1.lastSeen() > c2.lastSeen() ? 1 : -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,10 @@
|
|||||||
package kademlia.routing;
|
package kademlia.routing;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
import kademlia.node.Node;
|
import kademlia.node.Node;
|
||||||
import kademlia.node.NodeId;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A bucket in the Kademlia routing table
|
* A bucket in the Kademlia routing table
|
||||||
@ -17,11 +16,11 @@ public class KadBucket implements Bucket
|
|||||||
{
|
{
|
||||||
|
|
||||||
private final int depth;
|
private final int depth;
|
||||||
private final Map<NodeId, Contact> contacts;
|
private final Map<Contact, Contact> contacts;
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
contacts = new HashMap<>();
|
contacts = new TreeMap<>(new ContactLastSeenComparator());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,15 +35,19 @@ public class KadBucket implements Bucket
|
|||||||
public void insert(Contact c)
|
public void insert(Contact c)
|
||||||
{
|
{
|
||||||
/* @todo Check if the bucket is filled already and handle the situation */
|
/* @todo Check if the bucket is filled already and handle the situation */
|
||||||
/* Check if the contact is already in the bucket */
|
if (this.contacts.containsKey(c))
|
||||||
if (this.contacts.containsKey(c.getNode().getNodeId()))
|
|
||||||
{
|
{
|
||||||
/* @todo If it is, then move it to the front */
|
/**
|
||||||
/* @todo Possibly use a doubly linked list instead of an ArrayList */
|
* If the contact is already in the bucket, lets update that we've seen it
|
||||||
|
* We need to remove and re-add the contact to get the Sorted Set to update sort order
|
||||||
|
*/
|
||||||
|
Contact tmp = this.contacts.remove(c);
|
||||||
|
tmp.setSeenNow();
|
||||||
|
this.contacts.put(tmp, tmp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
contacts.put(c.getNode().getNodeId(), c);
|
contacts.put(c, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,25 +60,25 @@ public class KadBucket implements Bucket
|
|||||||
@Override
|
@Override
|
||||||
public boolean containsContact(Contact c)
|
public boolean containsContact(Contact c)
|
||||||
{
|
{
|
||||||
return this.contacts.containsKey(c.getNode().getNodeId());
|
return this.contacts.containsKey(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean containsNode(Node n)
|
public boolean containsNode(Node n)
|
||||||
{
|
{
|
||||||
return this.contacts.containsKey(n.getNodeId());
|
return this.containsContact(new Contact(n));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeContact(Contact c)
|
public void removeContact(Contact c)
|
||||||
{
|
{
|
||||||
this.contacts.remove(c.getNode().getNodeId());
|
this.contacts.remove(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeNode(Node n)
|
public void removeNode(Node n)
|
||||||
{
|
{
|
||||||
this.contacts.remove(n.getNodeId());
|
this.removeContact(new Contact(n));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -45,7 +45,7 @@ public class RoutingTable
|
|||||||
*
|
*
|
||||||
* @param c The contact to add
|
* @param c The contact to add
|
||||||
*/
|
*/
|
||||||
public final void insert(Contact c)
|
public synchronized final void insert(Contact c)
|
||||||
{
|
{
|
||||||
this.buckets[this.getBucketId(c.getNode().getNodeId())].insert(c);
|
this.buckets[this.getBucketId(c.getNode().getNodeId())].insert(c);
|
||||||
}
|
}
|
||||||
@ -55,7 +55,7 @@ public class RoutingTable
|
|||||||
*
|
*
|
||||||
* @param n The node to add
|
* @param n The node to add
|
||||||
*/
|
*/
|
||||||
public final void insert(Node n)
|
public synchronized final void insert(Node n)
|
||||||
{
|
{
|
||||||
this.buckets[this.getBucketId(n.getNodeId())].insert(n);
|
this.buckets[this.getBucketId(n.getNodeId())].insert(n);
|
||||||
}
|
}
|
||||||
|
54
src/kademlia/tests/RoutingTableSimulation.java
Normal file
54
src/kademlia/tests/RoutingTableSimulation.java
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package kademlia.tests;
|
||||||
|
|
||||||
|
import kademlia.Kademlia;
|
||||||
|
import kademlia.node.NodeId;
|
||||||
|
import kademlia.routing.RoutingTable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Testing how the routing table works and checking if everything works properly
|
||||||
|
*
|
||||||
|
* @author Joshua Kissoon
|
||||||
|
* @since 20140426
|
||||||
|
*/
|
||||||
|
public class RoutingTableSimulation
|
||||||
|
{
|
||||||
|
|
||||||
|
public RoutingTableSimulation()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
/* Setting up 2 Kad networks */
|
||||||
|
Kademlia kad1 = new Kademlia("JoshuaK", new NodeId("ASF45678947584567463"), 12049);
|
||||||
|
Kademlia kad2 = new Kademlia("Crystal", new NodeId("ASF45678947584567464"), 4585);
|
||||||
|
Kademlia kad3 = new Kademlia("Shameer", new NodeId("ASF45678947584567465"), 8104);
|
||||||
|
Kademlia kad4 = new Kademlia("Lokesh", new NodeId("ASF45678947584567466"), 8335);
|
||||||
|
Kademlia kad5 = new Kademlia("Chandu", new NodeId("ASF45678947584567467"), 13345);
|
||||||
|
|
||||||
|
RoutingTable rt = kad1.getNode().getRoutingTable();
|
||||||
|
|
||||||
|
rt.insert(kad2.getNode());
|
||||||
|
rt.insert(kad3.getNode());
|
||||||
|
rt.insert(kad4.getNode());
|
||||||
|
System.out.println(rt);
|
||||||
|
|
||||||
|
rt.insert(kad5.getNode());
|
||||||
|
System.out.println(rt);
|
||||||
|
|
||||||
|
rt.insert(kad3.getNode());
|
||||||
|
System.out.println(rt);
|
||||||
|
}
|
||||||
|
catch (IllegalStateException e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args)
|
||||||
|
{
|
||||||
|
new RoutingTableSimulation();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user