Only touch a bucket if a find request targets it.
authorCameron Dale <camrdale@gmail.com>
Fri, 9 May 2008 22:56:20 +0000 (15:56 -0700)
committerCameron Dale <camrdale@gmail.com>
Fri, 9 May 2008 22:56:20 +0000 (15:56 -0700)
Should prevent quiet nodes from keeping old contacts in the buckets.

apt_p2p_Khashmir/DHT.py
apt_p2p_Khashmir/db.py
apt_p2p_Khashmir/khashmir.py
apt_p2p_Khashmir/ktable.py

index a28a1e9..1236ebc 100644 (file)
@@ -451,7 +451,7 @@ class TestSimpleDHT(unittest.TestCase):
 class TestMultiDHT(unittest.TestCase):
     """More complicated 20-node tests for the DHT."""
     
-    timeout = 100
+    timeout = 200
     num = 20
     DHT_DEFAULTS = {'PORT': 9977,
                     'CHECKPOINT_INTERVAL': 300, 'CONCURRENT_REQS': 8,
index d0433e0..89ac04d 100644 (file)
@@ -211,9 +211,9 @@ class TestDB(unittest.TestCase):
             def __init__(self):
                 self.nodes = []
         bl1 = bl()
-        bl1.l.append(dummy())
+        bl1.nodes.append(dummy())
         bl2 = bl()
-        bl2.l.append(dummy2)
+        bl2.nodes.append(dummy2)
         buckets = [bl1, bl2]
         self.store.dumpRoutingTable(buckets)
         rt = self.store.getRoutingTable()
index d3ee9ee..968ddeb 100644 (file)
@@ -180,6 +180,9 @@ class KhashmirBase(protocol.Factory):
         @param callback: the method to call with the results, it must take 1
             parameter, the list of K closest nodes
         """
+        # Mark the bucket as having been accessed
+        self.table.touch(id)
+        
         # Start with our node
         nodes = [copy(self.node)]
 
@@ -405,6 +408,9 @@ class KhashmirRead(KhashmirBase):
         @param callback: the method to call with the results, it must take 1
             parameter, the list of nodes with values
         """
+        # Mark the bucket as having been accessed
+        self.table.touch(key)
+        
         # Start with ourself
         nodes = [copy(self.node)]
         
index 24ea93f..199c626 100644 (file)
@@ -95,6 +95,18 @@ class KTable:
         nodes.sort(lambda a, b, num=num: cmp(num ^ a.num, num ^ b.num))
         return nodes[:K]
         
+    def touch(self, id):
+        """Mark a bucket as having been looked up.
+
+        @type id: C{string} or C{int} or L{node.Node}
+        @param id: the ID in the bucket that was accessed
+        """
+        # Get the bucket number from the input
+        num = self._nodeNum(id)
+        i = self._bucketIndexForInt(num)
+        
+        self.buckets[i].touch()
+
     def _mergeBucket(self, i):
         """Merge unneeded buckets after removing a node.
         
@@ -190,7 +202,6 @@ class KTable:
                 # note that we removed the original and replaced it with the new one
                 # utilizing this nodes new contact info
                 self.buckets[i].add(node)
-                self.buckets[i].touch()
             return True
         
         # We don't have this node, check to see if the bucket is full
@@ -199,7 +210,6 @@ class KTable:
             if contacted:
                 node.updateLastSeen()
                 self.buckets[i].add(node)
-                self.buckets[i].touch()
                 log.msg('Added node to routing table: %s/%s' % (node.host, node.port))
                 return True
             return False
@@ -242,7 +252,6 @@ class KTable:
         except ValueError:
             return None
         else:
-            self.buckets[i].touch()
             return tstamp
     
     def invalidateNode(self, n):