Class DhtRoutingBucket

java.lang.Object
com.frostwire.jlibtorrent.DhtRoutingBucket

public final class DhtRoutingBucket extends Object
Statistics for a single bucket in the DHT routing table.

DhtRoutingBucket provides metrics about a single routing table bucket in the local Kademlia DHT implementation. The DHT routing table organizes known nodes into buckets based on distance from your own node ID. Each bucket contains active nodes and replacement candidates.

Understanding DHT Routing Buckets:
In Kademlia DHT, the routing table divides the node ID space into buckets:

  • Total Buckets: 160 buckets (one for each bit in SHA-1 hash)
  • Bucket Size: Typically 20 nodes (k-value)
  • Purpose: Organize known peers by their distance from your node ID
  • Strategy: Maintain nodes that are closer to you for efficient lookups

Bucket Organization:

 Closer to me                        Farther from me
 [Bucket 0] [Bucket 1] ... [Bucket 159]
   (20 nodes) (20 nodes)   (20 nodes)

 When you need to find something:
 - Start with closest bucket
 - Query nodes in that bucket
 - They tell you about closer nodes
 - Move to next bucket and repeat
 - Eventually narrow down to target
 

Monitoring DHT Routing Table:

 // Get routing buckets from DHT stats alert
 sm.addListener(new AlertListener() {
     public int[] types() {
         return new int[] {AlertType.DHT_STATS.swig()};
     }

     public void alert(Alert<?> alert) {
         DhtStatsAlert a = (DhtStatsAlert) alert;
         List<DhtRoutingBucket> buckets = a.routingBuckets();

         System.out.println("Total buckets: " + buckets.size());
         int totalNodes = 0;

         for (DhtRoutingBucket bucket : buckets) {
             int nodes = bucket.numNodes();
             totalNodes += nodes;

             if (nodes > 0) {
                 System.out.println("Bucket: " + nodes + " nodes, " +
                     bucket.numReplacements() + " replacements, " +
                     "last active " + bucket.lastActive() + "s ago");
             }
         }

         System.out.println("Total nodes in routing table: " + totalNodes);
     }
 });
 

Bucket Metrics Interpretation:

 DhtRoutingBucket bucket = ...;

 // Active nodes in this bucket
 int numNodes = bucket.numNodes();
 System.out.println("Active nodes: " + numNodes);

 // Replacement nodes (backup candidates)
 // Used when an active node becomes unresponsive
 int replacements = bucket.numReplacements();
 System.out.println("Replacement candidates: " + replacements);

 // How long since this bucket was used
 int lastActive = bucket.lastActive();
 System.out.println("Last active: " + lastActive + " seconds ago");

 // Bucket health assessment
 if (numNodes < 5) {
     System.out.println("Warning: Few nodes in this bucket");
 }

 if (replacements == 0) {
     System.out.println("Warning: No replacement candidates");
 }

 if (lastActive > 3600) {
     System.out.println("Warning: This bucket hasn't been used in over an hour");
 }
 

Analyzing Routing Table Health:

 List<DhtRoutingBucket> buckets = dhtStatsAlert.routingBuckets();

 // Count routing table status
 int totalNodes = 0;
 int totalReplacements = 0;
 int activeBuckets = 0;

 for (DhtRoutingBucket bucket : buckets) {
     int nodes = bucket.numNodes();
     if (nodes > 0) {
         totalNodes += nodes;
         totalReplacements += bucket.numReplacements();
         activeBuckets++;
     }
 }

 System.out.println("===== DHT Routing Table Status =====");
 System.out.println("Active buckets: " + activeBuckets + " / " + buckets.size());
 System.out.println("Total nodes: " + totalNodes);
 System.out.println("Replacement nodes: " + totalReplacements);
 System.out.println("Average nodes per bucket: " + (totalNodes / Math.max(activeBuckets, 1)));

 // Network connectivity assessment
 if (activeBuckets < 10) {
     System.out.println("Network Status: Poor (few active buckets)");
 } else if (activeBuckets < 50) {
     System.out.println("Network Status: Fair (moderate connectivity)");
 } else if (activeBuckets < 100) {
     System.out.println("Network Status: Good (well connected)");
 } else {
     System.out.println("Network Status: Excellent (highly connected)");
 }
 

Bucket Refresh Strategy:

 // Oldest buckets (least recently used) should be refreshed
 List<DhtRoutingBucket> buckets = dhtStatsAlert.routingBuckets();

 DhtRoutingBucket stalestBucket = null;
 int maxInactivity = 0;

 for (DhtRoutingBucket bucket : buckets) {
     if (bucket.numNodes() > 0) {
         int inactivity = bucket.lastActive();
         if (inactivity > maxInactivity) {
             maxInactivity = inactivity;
             stalestBucket = bucket;
         }
     }
 }

 if (stalestBucket != null && maxInactivity > 1800) {
     System.out.println("Routing table needs refresh - last activity was " +
         maxInactivity + " seconds ago");
 }
 

DHT Bootstrap and Network Join:

 // When you start, routing table is empty
 // Bootstrap process populates it:

 // 1. Connect to known bootstrap nodes
 // 2. Query them to find nodes closer to your ID
 // 3. Query those nodes, getting even closer ones
 // 4. Gradually fill routing table with nearby nodes
 //
 // After bootstrap:
 // - You'll have ~1600-3200 total nodes (160 buckets * 20 nodes)
 // - Buckets are maintained automatically via lookups
 // - Periodic refresh keeps far buckets alive
 
See Also:
  • Constructor Details

    • DhtRoutingBucket

      public DhtRoutingBucket(com.frostwire.jlibtorrent.swig.dht_routing_bucket t)
  • Method Details

    • swig

      public com.frostwire.jlibtorrent.swig.dht_routing_bucket swig()
    • numNodes

      public int numNodes()
      The total number of nodes in the routing table.
      Returns:
    • numReplacements

      public int numReplacements()
      The total number of replacement nodes in the routing table.
      Returns:
    • lastActive

      public int lastActive()
      Number of seconds since last activity.
      Returns: