³ò
ô=£Cc           @   sÞ   d  d k  l Z d  d k Td  d k Td  d k Z d  d k Z d  d k l Z l	 Z	 l
 Z
 l Z l Z d  d k l Z d d d „  ƒ  YZ d d d	 „  ƒ  YZ d  d k Z d
 e i f d „  ƒ  YZ e d j o e i ƒ  n d S(   iÿÿÿÿ(   t   bttime(   t   *N(   t   Kt   HASH_LENGTHt   NULL_IDt   MAX_FAILURESt   MIN_PING_INTERVAL(   t   Nodet   KTablec           B   sz   e  Z d  Z d „  Z d „  Z d „  Z e d „ Z d „  Z d „  Z	 d e
 d „ Z d	 „  Z d
 „  Z d „  Z d „  Z RS(   s>   local routing table for a kademlia like distributed hash tablec         C   s6   | |  _  t g  d d t ƒ g |  _ |  i | ƒ d  S(   Nl    l    (   t   nodet   KBucketR   t   bucketst
   insertNode(   t   selfR	   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyt   __init__   s    	c         C   s   t  |  i | ƒ S(   s,   the index of the bucket that should hold int(   t   bisect_leftR   (   R   t   num(    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyt   _bucketIndexForInt   s    c         C   s   |  i  |  i | ƒ S(   N(   R   R   (   R   R   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyt   bucketForInt    s    c      	   C   s2  t  | t ƒ o t i | ƒ } nQ t  | t ƒ o | i } n4 t  | t ƒ p t  | t ƒ o
 | } n
 t d ‚ g  } |  i	 | ƒ } y |  i
 | i | ƒ } Wn t j
 o n	 X| g S| |  i
 | i } | p3 g  } | D] } | i p | | qå qå ~ } n t | ƒ t j  o÷ | d }	 | d }
 xà t | ƒ t j  oÈ |	 d j p |
 t |  i
 ƒ j  o¥ |	 d j o | |  i
 |	 i } n |
 t |  i
 ƒ j  o | |  i
 |
 i } n |	 d }	 |
 d }
 | p3 g  } | D] } | i p | | qæqæ~ } q7q7Wn | i | d „ ƒ | t  S(   sN   
            return K nodes in our own local table closest to the ID.
        s*   findNodes requires an int, string, or Nodei   i    c         S   s   t  | |  i A| | i Aƒ S(    (   t   cmpR   (   t   at   bR   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyt   <lambda>O   s    (   t
   isinstancet   strt   hasht   intifyR   R   t   intt   longt	   TypeErrorR   R   t   getNodeWithIntt
   ValueErrort   lt   invalidt   lenR   t   sort(   R   t   idR!   R   t   nodest   iR	   t   _[1]R   t   mint   maxt   _[2](    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyt	   findNodes#   s@     
	3

 6

<c         C   s°   | i  | i d } t g  | i  | | i  ƒ } |  i i |  i i | i ƒ d | ƒ | i  | | _  xC | i D]7 } | i | i  j o | i | ƒ | i	 | ƒ qq qq Wd  S(   Ni   i   (
   R)   R(   R
   R   t   insertt   indexR    R   t
   removeNodet   addNode(   R   R   t   diffR   t   anode(    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyt   _splitBucketR   s    & c         C   sš   |  i  | i ƒ } |  i | i | ƒ o |  i | i | ƒ n | o/ |  i | i | ƒ o |  i | i | ƒ n  | o |  i | i | ƒ n d S(   st   this is used by clients to replace a node returned by insertNode after
        it fails to respond to a Pong messageN(   R   R   R   t   hasNodeR.   t   seenNodeR/   (   R   t   stalet   newR&   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyt   replaceStaleNode]   s    i   c         C   sZ  | i  t j p | i  |  i i  j o d Sn | o | i ƒ  n |  i | i ƒ } |  i | i | ƒ o§ |  i | i i	 | i ƒ } |  i | i | } | o$ | i
 | _
 |  i | i | ƒ nE | i d j o4 | i | i j o! | i | i j o | i ƒ  n d Sn |  i | i ƒ  p |  i | i | ƒ d Sn t ƒ  } d „  } g  }	 |  i | i i ƒ  D] }
 |
 i o |	 |
 qpqp~	 } t | ƒ oÄ | o¼ | i | ƒ xJ | oB |  i | i | d ƒ o& |  i | i | d i =| d } q¹W| o4 | d i d j o  | d i t j  o | d Sqe| o |  i | d | ƒ d Sqen g  } |  i | i D]% } | | i t j o | | qzqz~ } t | ƒ o! | o | i | ƒ | d Sn |  i | i |  i j o |  i | i j  n p d Sn t |  i ƒ t j o d GHd Sn |  i |  i | ƒ |  i | | ƒ S(   sF   
        this insert the node, returning None if successful, returns the oldest node in the bucket if it's full
        the caller responsible for pinging the returned node and calling replaceStaleNode if it is found to be stale!!
        contacted means that yes, we contacted THEM and we know the node is reachable
        Ni    c         S   s:   |  i  | i  j o d Sn | i  |  i  j o d Sn d S(   Ni   iÿÿÿÿi    (   t   lastSeen(   R   R   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyt   lsŒ   s
    i   s    Hash Table is FULL!  Increase K!(   R$   R   R	   t   updateLastSeenR   R   R   R3   R    R-   t   ageR4   R8   t   portt   hostt
   bucketFullR/   t   timeR!   t   valuesR"   R#   t   failsR   R7   R   R(   R)   R   R2   R   (   R   R	   t	   contactedt   nocheckR&   t   itt   xnodet   tR9   R'   t   xR!   R*   t   nR5   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyR   k   sT    &6		? #/C5c         C   sk   y |  i  | ƒ d } Wn t j
 o d Sn8 X| i } | i ƒ  |  i | i ƒ } | i | ƒ | Sd S(   sf   call this any time you get a message from a node
        it will update it in the table if it's there i    N(   R+   t
   IndexErrort   NoneR8   R:   R   R   R4   (   R   R$   RH   t   tstampt   bucket(    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyt   justSeenNode³   s    		
c         C   s2   t  | _ |  i | i ƒ |  _ |  i i | ƒ d S(   sR   
            forget about node n - use when you know that node is invalid
        N(   t   TrueR!   R   R   RL   t   invalidateNode(   R   RH   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyRO   Á   s    	c         C   s_   y |  i  | i ƒ d } Wn t j
 o d Sn) X| i ƒ  t i j o |  i | ƒ n d S(   sN    call this when a node fails to respond to a message, to invalidate that node i    N(   R+   R   RI   RJ   t	   msgFailedt   constR   RO   (   R   R	   RH   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyt
   nodeFailedÉ   s    	c         C   s   d d t  |  i ƒ d S(   s7    estimated number of connectable nodes in global table i   i   i   (   R"   R   (   R   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyt   numPeersÓ   s    (   t   __name__t
   __module__t   __doc__R   R   R   RN   R+   R2   R7   t   FalseR   RM   RO   RR   RS   (    (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyR      s   			/		H			
R
   c           B   s°   e  Z d Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d	 „  Z	 d
 „  Z
 d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z RS(   R(   R)   t   lastAccessedc         C   s=   | |  _  h  |  _ h  |  _ | |  _ | |  _ t ƒ  |  _ d  S(   N(   R    R-   R!   R(   R)   R?   RX   (   R   t   contentsR(   R)   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyR   Ù   s    					c         C   s   t  ƒ  |  _ d  S(   N(   R?   RX   (   R   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyt   touchá   s    c         C   s:   | i  | i  j o d Sn | i  | i  j o d Sn d S(   Ni   iÿÿÿÿi    (   R8   (   R   R   R   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyt   lacmpä   s
    c         C   s   |  i  i |  i ƒ d  S(   N(   R    R#   R[   (   R   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyR#   ë   s    c         C   s1   y |  i  | } Wn t j
 o t ‚ n X| S(   N(   R-   t   KeyErrorR   (   R   R   R	   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyR   î   s
    c         C   sj   t  |  i ƒ t j o d  Sn |  i i | i ƒ o d  Sn |  i i | ƒ | |  i | i <|  i ƒ  d  S(   N(   R"   R    R   R-   t   has_keyR   t   appendRZ   (   R   R	   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyR/   õ   s    c         C   sx   |  i  i | i ƒ p t ‚ |  i |  i i  | i ƒ =|  i  | i =y |  i | i =Wn t j
 o n X|  i ƒ  d  S(   N(   R-   R]   R   t   AssertionErrorR    R!   R\   RZ   (   R   R	   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyR.   þ   s    c         C   s   | |  i  | i <d  S(   N(   R!   R   (   R   R	   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyRO     s    c         C   sj   y |  i  | i =Wn t j
 o n X|  i i | i ƒ } |  i | =|  i i | ƒ | |  i | i <d  S(   N(   R!   R   R\   R    R-   R^   (   R   R	   RD   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyR4     s    
c         C   s   |  i  i | i ƒ S(   N(   R-   R]   R   (   R   R	   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyR3     s    c         C   s   t  |  i ƒ t j S(   N(   R"   R    R   (   R   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyR>     s    c         C   s    d t  |  i ƒ |  i |  i f S(   Ns   <KBucket %d items (%d to %d)>(   R"   R    R(   R)   (   R   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyt   __repr__  s    c         C   s*   t  | t ƒ o | i } n |  i | j S(   N(   R   R   R   R)   (   R   R   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyt   __lt__!  s     c         C   s*   t  | t ƒ o | i } n |  i | j  S(   N(   R   R   R   R(   (   R   R   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyt   __le__$  s     c         C   s*   t  | t ƒ o | i } n |  i | j S(   N(   R   R   R   R(   (   R   R   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyt   __gt__'  s     c         C   s*   t  | t ƒ o | i } n |  i | j S(   N(   R   R   R   R)   (   R   R   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyt   __ge__*  s     c         C   s:   t  | t ƒ o | i } n |  i | j o |  i | j S(   N(   R   R   R   R(   R)   (   R   R   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyt   __eq__-  s     c         C   s:   t  | t ƒ o | i } n |  i | j p |  i | j  S(   N(   R   R   R   R(   R)   (   R   R   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyt   __ne__0  s     (   s   mins   maxs   lastAccessed(   RT   RU   t	   __slots__R   RZ   R[   R#   R   R/   R.   RO   R4   R3   R>   R`   Ra   Rb   Rc   Rd   Re   Rf   (    (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyR
   ×   s&   								
		
								t
   TestKTablec           B   s,   e  Z d  „  Z d „  Z d „  Z d „  Z RS(   c         C   s7   t  ƒ  i t i ƒ  d d ƒ |  _ t |  i ƒ |  _ d  S(   Nt	   localhostiÒ  (   R   t   initR   t   newIDR   R   RF   (   R   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyt   setUp9  s    !c         C   s   t  ƒ  i t i ƒ  d d ƒ |  _ |  i i |  i ƒ |  i t |  i i	 d i
 ƒ d ƒ |  i |  i i	 d i
 d |  i ƒ d  S(   NRi   iÓ  i    i   (   R   Rj   R   Rk   R   RF   R   t   assertEqualR"   R   R    (   R   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyt   testAddNode=  s    !#c         C   sD   |  i  ƒ  |  i i |  i ƒ |  i t |  i i d i ƒ d ƒ d  S(   Ni    (   Rn   RF   RO   R   Rm   R"   R   R    (   R   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyt
   testRemoveC  s    
c         C   s¼   |  i  ƒ  xu t t i d ƒ D]` } |  i i |  i ƒ |  i t |  i i	 d i
 ƒ d ƒ |  i |  i i	 d i
 d |  i ƒ q W|  i i |  i ƒ |  i t |  i i	 d i
 ƒ d ƒ d  S(   Ni   i    (   Rn   t   rangeRQ   R   RF   RR   R   Rm   R"   R   R    (   R   R&   (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyt   testFailH  s    
 #((   RT   RU   Rl   Rn   Ro   Rq   (    (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pyRh   8  s   			t   __main__(    (    (   t   BitTorrent.platformR    R?   t   bisectt   typest   khashR   RQ   R   R   R   R   R   R	   R   R   R
   t   unittestt   TestCaseRh   RT   t   main(    (    (    sT   /afs/sipb.mit.edu/project/outland/src/BitTorrent/BitTorrent-4.2.2/khashmir/ktable.pys   <module>   s   

(Ã_