mirror of
https://github.com/ChronosX88/KademliaDHT.git
synced 2024-12-23 00:01:46 +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
|
||||
{
|
||||
|
||||
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 OPERATION_TIMEOUT = 3000;
|
||||
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.
|
||||
* - Information such as
|
||||
* -- Last alive time
|
||||
* -- Last seen time
|
||||
*
|
||||
* @author Joshua Kissoon
|
||||
* @since 20140425
|
||||
* @updated 20140426
|
||||
*/
|
||||
public class Contact
|
||||
public class Contact implements Comparable<Contact>
|
||||
{
|
||||
|
||||
private final Node n;
|
||||
private long lastSeen;
|
||||
|
||||
/**
|
||||
* Create a contact object
|
||||
*
|
||||
* @param n The node associated with this contact
|
||||
*/
|
||||
public Contact(Node n)
|
||||
{
|
||||
this.n = n;
|
||||
this.lastSeen = System.currentTimeMillis() / 1000L;
|
||||
}
|
||||
|
||||
public Node getNode()
|
||||
{
|
||||
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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import kademlia.node.Node;
|
||||
import kademlia.node.NodeId;
|
||||
|
||||
/**
|
||||
* A bucket in the Kademlia routing table
|
||||
@ -17,11 +16,11 @@ public class KadBucket implements Bucket
|
||||
{
|
||||
|
||||
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)
|
||||
{
|
||||
/* @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.getNode().getNodeId()))
|
||||
if (this.contacts.containsKey(c))
|
||||
{
|
||||
/* @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
|
||||
{
|
||||
contacts.put(c.getNode().getNodeId(), c);
|
||||
contacts.put(c, c);
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,25 +60,25 @@ public class KadBucket implements Bucket
|
||||
@Override
|
||||
public boolean containsContact(Contact c)
|
||||
{
|
||||
return this.contacts.containsKey(c.getNode().getNodeId());
|
||||
return this.contacts.containsKey(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsNode(Node n)
|
||||
{
|
||||
return this.contacts.containsKey(n.getNodeId());
|
||||
return this.containsContact(new Contact(n));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeContact(Contact c)
|
||||
{
|
||||
this.contacts.remove(c.getNode().getNodeId());
|
||||
this.contacts.remove(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNode(Node n)
|
||||
{
|
||||
this.contacts.remove(n.getNodeId());
|
||||
this.removeContact(new Contact(n));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -45,7 +45,7 @@ public class RoutingTable
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
@ -55,7 +55,7 @@ public class RoutingTable
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
|
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