Ë
    ojÉ$  ã                   ó  — d Z ddlmZ ddlmZ ddlmZmZ ddlmZ  G d„ d«      Z	 G d„ d	e«      Z
 ee
«       G d
„ d«      «       Z G d„ de«      Z G d„ de«      Z G d„ dej                  «      Z G d„ de«      Z G d„ d«      Zy)a¼  
Hierarchical Token Bucket traffic shaping.

Patterned after U{Martin Devera's Hierarchical Token Bucket traffic
shaper for the Linux kernel<http://luxik.cdi.cz/~devik/qos/htb/>}.

@seealso: U{HTB Linux queuing discipline manual - user guide
  <http://luxik.cdi.cz/~devik/qos/htb/manual/userg.htm>}
@seealso: U{Token Bucket Filter in Linux Advanced Routing & Traffic Control
    HOWTO<http://lartc.org/howto/lartc.qdisc.classless.html#AEN682>}
é    )Útime)ÚOptional)Ú	InterfaceÚimplementer)Úpcpc                   óR   — e Zd ZU dZdZee   ed<   dZee   ed<   dZ	d	d„Z
d„ Zd„ Zy)
ÚBucketaë  
    Implementation of a Token bucket.

    A bucket can hold a certain number of tokens and it drains over time.

    @cvar maxburst: The maximum number of tokens that the bucket can
        hold at any given time. If this is L{None}, the bucket has
        an infinite size.
    @type maxburst: C{int}
    @cvar rate: The rate at which the bucket drains, in number
        of tokens per second. If the rate is L{None}, the bucket
        drains instantaneously.
    @type rate: C{int}
    NÚmaxburstÚrater   c                 ó>   — d| _         || _        t        «       | _        y)a(  
        Create a L{Bucket} that may have a parent L{Bucket}.

        @param parentBucket: If a parent Bucket is specified,
            all L{add} and L{drip} operations on this L{Bucket}
            will be applied on the parent L{Bucket} as well.
        @type parentBucket: L{Bucket}
        r   N)ÚcontentÚparentBucketr   ÚlastDrip)Úselfr   s     ú7/usr/lib/python3/dist-packages/twisted/protocols/htb.pyÚ__init__zBucket.__init__3   s   € ð ˆŒØ(ˆÔÜ›ˆ�ó    c                 ó  — | j                  «        | j                  €|}n#t        || j                  | j                  z
  «      }| j                  �| j                  j                  |«      }| xj                  |z  c_        |S )at  
        Adds tokens to the L{Bucket} and its C{parentBucket}.

        This will add as many of the C{amount} tokens as will fit into both
        this L{Bucket} and its C{parentBucket}.

        @param amount: The number of tokens to try to add.
        @type amount: C{int}

        @returns: The number of tokens that actually fit.
        @returntype: C{int}
        )Údripr
   Úminr   r   Úadd)r   ÚamountÚ	allowables      r   r   z
Bucket.add@   sk   € ð 	�	‰	ŒØ�=‰=Ð Ø‰Iä˜F D§M¡M°D·L±LÑ$@ÓAˆIà×ÑÐ(Ø×)Ñ)×-Ñ-¨iÓ8ˆIØ�Š˜	Ñ!�ØÐr   c                 ó.  — | j                   �| j                   j                  «        | j                  €d| _        nMt	        «       }|| j
                  z
  }|| j                  z  }t        d| j                  |z
  «      | _        || _        | j                  dk(  S )zê
        Let some of the bucket drain.

        The L{Bucket} drains at the rate specified by the class
        variable C{rate}.

        @returns: C{True} if the bucket is empty after this drip.
        @returntype: C{bool}
        r   )r   r   r   r   r   r   Úmax)r   ÚnowÚ	deltaTimeÚdeltaTokenss       r   r   zBucket.dripX   sƒ   € ð ×ÑÐ(Ø×Ñ×"Ñ"Ô$à�9‰9ÐØˆD�Lä“&ˆCØ˜dŸm™mÑ+ˆIØ# d§i¡iÑ/ˆKÜ˜q $§,¡,°Ñ"<Ó=ˆDŒLØˆDŒMØ�|‰|˜qÑ Ð r   ©N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r
   r   ÚintÚ__annotations__r   Ú	_refcountr   r   r   © r   r   r	   r	      s9   … ñð #€Hˆh�s‰mÓ"Ø€Dˆ(�3‰-Óà€Ióòó0!r   r	   c                   ó   — e Zd Zd„ Zy)ÚIBucketFilterc                   ó   — y)zn
        Return a L{Bucket} corresponding to the provided parameters.

        @returntype: L{Bucket}
        Nr'   )Ú
somethingsÚsome_kws     r   ÚgetBucketForzIBucketFilter.getBucketForq   s   � r   N)r    r!   r"   r-   r'   r   r   r)   r)   p   s   „ ór   r)   c                   óD   — e Zd ZU dZeZdZee   e	d<   dd„Z
d„ Zd„ Zd„ Zy)	ÚHierarchicalBucketFilterz÷
    Filter things into buckets that can be nested.

    @cvar bucketFactory: Class of buckets to make.
    @type bucketFactory: L{Bucket}
    @cvar sweepInterval: Seconds between sweeping out the bucket cache.
    @type sweepInterval: C{int}
    NÚsweepIntervalc                 ó>   — i | _         || _        t        «       | _        y r   )ÚbucketsÚparentFilterr   Ú	lastSweep)r   r3   s     r   r   z!HierarchicalBucketFilter.__init__‡   s   € ØˆŒØ(ˆÔÜ›ˆ�r   c                 ó‚  — | j                   �4t        «       | j                  z
  | j                   kD  r| j                  «        | j                  r! | j                  j
                  | g|¢­i |¤Ž}nd} | j                  |i |¤Ž}| j                  j                  |«      }|€ | j                  |«      }|| j                  |<   |S )zã
        Find or create a L{Bucket} corresponding to the provided parameters.

        Any parameters are passed on to L{getBucketKey}, from them it
        decides which bucket you get.

        @returntype: L{Bucket}
        N)
r0   r   r4   Úsweepr3   r-   ÚgetBucketKeyr2   ÚgetÚbucketFactory)r   ÚaÚkwr   ÚkeyÚbuckets         r   r-   z%HierarchicalBucketFilter.getBucketForŒ   sµ   € ð ×ÑÐ*Ü‹V�d—n‘nÑ$¨×(:Ñ(:Ò:à�J‰JŒLà×ÒØ9˜4×,Ñ,×9Ñ9¸$ÐIÀÒIÀbÑI‰LàˆLàˆd×Ñ Ð) bÑ)ˆØ—‘×!Ñ! #Ó&ˆØˆ>Ø×'Ñ'¨Ó5ˆFØ &ˆD�L‰L˜ÑØˆr   c                  ó   — y)a%  
        Construct a key based on the input parameters to choose a L{Bucket}.

        The default implementation returns the same key for all
        arguments. Override this method to provide L{Bucket} selection.

        @returns: Something to be used as a key in the bucket cache.
        Nr'   )r   r:   r;   s      r   r7   z%HierarchicalBucketFilter.getBucketKey¦   s   € ð r   c                 óÆ   — | j                   j                  «       D ]5  \  }}|j                  «       }|j                  dk(  sŒ&|sŒ)| j                   |= Œ7 t	        «       | _        y)z'
        Remove empty buckets.
        r   N)r2   Úitemsr   r&   r   r4   )r   r<   r=   Úbucket_is_emptys       r   r6   zHierarchicalBucketFilter.sweep±   sV   € ð  Ÿ<™<×-Ñ-Ó/ò 	&‰KˆC�Ø$Ÿk™k›mˆOØ× Ñ  AÓ%ª?Ø—L‘L Ñ%ð	&ô
 ›ˆ�r   r   )r    r!   r"   r#   r	   r9   r0   r   r$   r%   r   r-   r7   r6   r'   r   r   r/   r/   y   s0   … ñð €MØ#'€M�8˜C‘=Ó'ó ò
ò4	ó	 r   r/   c                   ó   — e Zd ZdZdZd„ Zy)ÚFilterByHostzF
    A Hierarchical Bucket filter with a L{Bucket} for each host.
    i°  c                 ó(   — |j                  «       d   S ©Né   )ÚgetPeer©r   Ú	transports     r   r7   zFilterByHost.getBucketKeyÄ   ó   € Ø× Ñ Ó" 1Ñ%Ð%r   N©r    r!   r"   r#   r0   r7   r'   r   r   rC   rC   ½   s   „ ñð €Mó&r   rC   c                   ó   — e Zd ZdZdZd„ Zy)ÚFilterByServerzI
    A Hierarchical Bucket filter with a L{Bucket} for each service.
    Nc                 ó(   — |j                  «       d   S )Né   )ÚgetHostrH   s     r   r7   zFilterByServer.getBucketKeyÏ   rJ   r   rK   r'   r   r   rM   rM   È   s   „ ñð €Mó&r   rM   c                   ó&   — e Zd ZdZdZd„ Zd„ Zd„ Zy)ÚShapedConsumerzL
    Wraps a C{Consumer} and shapes the rate at which it receives data.
    Fc                 ó�   — t         j                  j                  | |«       || _        | j                  xj                  dz  c_        y rE   )r   ÚProducerConsumerProxyr   r=   r&   )r   Úconsumerr=   s      r   r   zShapedConsumer.__init__Ü   s4   € Ü×!Ñ!×*Ñ*¨4°Ô:ØˆŒØ�‰×Ò Ñ"Ör   c                 ó�   — | j                   j                  t        |«      «      }t        j                  j                  | |d | «      S r   )r=   r   Úlenr   rT   Ú_writeSomeData)r   Údatar   s      r   rX   zShapedConsumer._writeSomeDataá   s9   € ð
 —‘—‘¤ T£Ó+ˆÜ×(Ñ(×7Ñ7¸¸dÀ7ÀF¸mÓLÐLr   c                 ó€   — t         j                  j                  | «       | j                  xj                  dz  c_        y rE   )r   rT   ÚstopProducingr=   r&   )r   s    r   r[   zShapedConsumer.stopProducingé   s+   € Ü×!Ñ!×/Ñ/°Ô5Ø�‰×Ò Ñ"Ör   N)r    r!   r"   r#   ÚiAmStreamingr   rX   r[   r'   r   r   rR   rR   Ó   s   „ ñð €Lò#ò
Mó#r   rR   c                   ó   — e Zd ZdZdZd„ Zy)ÚShapedTransportaR  
    Wraps a C{Transport} and shapes the rate at which it receives data.

    This is a L{ShapedConsumer} with a little bit of magic to provide for
    the case where the consumer it wraps is also a C{Transport} and people
    will be attempting to access attributes this does not proxy as a
    C{Consumer} (e.g. C{loseConnection}).
    Fc                 ó.   — t        | j                  |«      S r   )ÚgetattrrU   )r   Únames     r   Ú__getattr__zShapedTransport.__getattr__ü   s   € ô �t—}‘} dÓ+Ð+r   N)r    r!   r"   r#   r\   rb   r'   r   r   r^   r^   î   s   „ ñð €Ló,r   r^   c                   ó   — e Zd ZdZd„ Zd„ Zy)ÚShapedProtocolFactorya�  
    Dispense C{Protocols} with traffic shaping on their transports.

    Usage::

        myserver = SomeFactory()
        myserver.protocol = ShapedProtocolFactory(myserver.protocol,
                                                  bucketFilter)

    Where C{SomeServerFactory} is a L{twisted.internet.protocol.Factory}, and
    C{bucketFilter} is an instance of L{HierarchicalBucketFilter}.
    c                 ó    — || _         || _        y)aœ  
        Tell me what to wrap and where to get buckets.

        @param protoClass: The class of C{Protocol} this will generate
          wrapped instances of.
        @type protoClass: L{Protocol<twisted.internet.interfaces.IProtocol>}
          class
        @param bucketFilter: The filter which will determine how
          traffic is shaped.
        @type bucketFilter: L{HierarchicalBucketFilter}.
        N)ÚprotocolÚbucketFilter)r   Ú
protoClassrg   s      r   r   zShapedProtocolFactory.__init__  s   € ð #ˆŒØ(ˆÕr   c                 ó`   ‡ ‡—  ‰ j                   |i |¤Ž}|j                  Šˆˆ fd„}||_        |S )zÔ
        Make a C{Protocol} instance with a shaped transport.

        Any parameters will be passed on to the protocol's initializer.

        @returns: A C{Protocol} instance with a L{ShapedTransport}.
        c                 ób   •— ‰j                   j                  | «      }t        | |«      } ‰|«      S r   )rg   r-   r^   )rI   r=   ÚshapedTransportÚorigMakeConnectionr   s      €€r   ÚmakeConnectionz6ShapedProtocolFactory.__call__.<locals>.makeConnection,  s0   ø€ Ø×&Ñ&×3Ñ3°IÓ>ˆFÜ-¨i¸Ó@ˆOÙ% oÓ6Ð6r   )rf   rm   )r   r:   r;   Úprotorm   rl   s   `    @r   Ú__call__zShapedProtocolFactory.__call__!  s:   ù€ ð �—‘˜qÐ' BÑ'ˆØ"×1Ñ1Ðõ	7ð
  .ˆÔØˆr   N)r    r!   r"   r#   r   ro   r'   r   r   rd   rd     s   „ ñò)ó"r   rd   N)r#   r   Útypingr   Úzope.interfacer   r   Útwisted.protocolsr   r	   r)   r/   rC   rM   rT   rR   r^   rd   r'   r   r   ú<module>rs      s•   ðñ
õ  Ý ç 1å !÷O!ñ O!ôd�Iô ñ ˆ]Ó÷@ ð @ ó ð@ ôF&Ð+ô &ô&Ð-ô &ô#�S×.Ñ.ô #ô6,�nô ,÷(0ò 0r   