§
    ÈtºfÉ$  ã                   óD  — 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dS )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                   ó`   — 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dS )
Ú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                 óH   — d| _         || _        t          ¦   «         | _        dS )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     úT/var/www/surfInsights/venv3-11/lib/python3.11/site-packages/twisted/protocols/htb.pyÚ__init__zBucket.__init__3   s"   € ð ˆŒØ(ˆÔÝ™œˆŒˆˆó    c                 óÞ   — |                       ¦   «          | j        €|}nt          || j        | j        z
  ¦  «        }| 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@   sm   € ð 	�	Š	‰ŒˆØŒ=Ð ØˆIˆIå˜F D¤M°D´LÑ$@ÑAÔAˆIàÔÐ(ØÔ)×-Ò-¨iÑ8Ô8ˆIØˆŒ˜	Ñ!ˆŒØÐr   c                 ó  — | j         �| j                              ¦   «          | j        €d| _        nFt	          ¦   «         }|| 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}
        Nr   )r   r   r   r   r   r   Úmax)r   ÚnowÚ	deltaTimeÚdeltaTokenss       r   r   zBucket.dripX   s€   € ð ÔÐ(ØÔ×"Ò"Ñ$Ô$Ð$àŒ9ÐØˆDŒLˆLå‘&”&ˆCØ˜dœmÑ+ˆIØ# d¤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	      s�   € € € € € € ðð ð #€Hˆh�sŒmÐ"Ð"Ñ"Ø€Dˆ(�3Œ-ÐÐÑà€Iðð ð ð ðð ð ð0!ð !ð !ð !ð !r   r	   c                   ó   — e Zd Zd„ ZdS )ÚIBucketFilterc                  ó   — dS )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                   óL   — e Zd ZU dZeZdZee         e	d<   dd„Z
d„ Zd„ Zd„ ZdS )	Ú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                 óH   — i | _         || _        t          ¦   «         | _        d S r   )ÚbucketsÚparentFilterr   Ú	lastSweep)r   r3   s     r   r   z!HierarchicalBucketFilter.__init__‡   s    € ØˆŒØ(ˆÔÝ™œˆŒˆˆr   c                 óJ  — | j         �3t          ¦   «         | j        z
  | j         k    r|                      ¦   «          | j        r | j        j        | g|¢R i |¤Ž}nd} | j        |i |¤Ž}| 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ŒV�d”nÑ$¨Ô(:Ò:Ð:à�JŠJ‰LŒLˆLàÔð 	 Ø9˜4Ô,Ô9¸$ÐIÀÐIÐIÐIÀbÐIÐIˆLˆLàˆLàˆdÔ Ð) bÐ)Ð)ˆØ”×!Ò! #Ñ&Ô&ˆØˆ>Ø×'Ò'¨Ñ5Ô5ˆFØ &ˆDŒL˜ÑØˆr   c                 ó   — dS )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	   € ð ˆtr   c                 ó¼   — | j                              ¦   «         D ].\  }}|                     ¦   «         }|j        dk    r
|r| j         |= Œ/t	          ¦   «         | _        dS )z'
        Remove empty buckets.
        r   N)r2   Úitemsr   r&   r   r4   )r   r<   r=   Úbucket_is_emptys       r   r6   zHierarchicalBucketFilter.sweep±   s_   € ð  œ<×-Ò-Ñ/Ô/ð 	&ð 	&‰KˆC�Ø$Ÿkšk™mœmˆOØÔ  AÒ%Ð%¨?Ð%Ø”L Ð%øå™œˆŒˆˆr   r   )r    r!   r"   r#   r	   r9   r0   r   r$   r%   r   r-   r7   r6   r'   r   r   r/   r/   y   s|   € € € € € € ðð ð €MØ#'€M�8˜C”=Ð'Ð'Ñ'ð ð  ð  ð  ð
ð ð ð4	ð 	ð 	ð	 ð 	 ð 	 ð 	 ð 	 r   r/   c                   ó   — e Zd ZdZdZd„ ZdS )ÚFilterByHostzF
    A Hierarchical Bucket filter with a L{Bucket} for each host.
    i°  c                 ó6   — |                      ¦   «         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   ½   s4   € € € € € ðð ð €Mð&ð &ð &ð &ð &r   rC   c                   ó   — e Zd ZdZdZd„ ZdS )ÚFilterByServerzI
    A Hierarchical Bucket filter with a L{Bucket} for each service.
    Nc                 ó6   — |                      ¦   «         d         S )Né   )ÚgetHostrH   s     r   r7   zFilterByServer.getBucketKeyÏ   rJ   r   rK   r'   r   r   rM   rM   È   s4   € € € € € ðð ð €Mð&ð &ð &ð &ð &r   rM   c                   ó(   — e Zd ZdZdZd„ Zd„ Zd„ ZdS )ÚShapedConsumerzL
    Wraps a C{Consumer} and shapes the rate at which it receives data.
    Fc                 ó~   — t           j                             | |¦  «         || _        | j        xj        dz  c_        d S rE   )r   ÚProducerConsumerProxyr   r=   r&   )r   Úconsumerr=   s      r   r   zShapedConsumer.__init__Ü   s>   € ÝÔ!×*Ò*¨4°Ñ:Ô:Ð:ØˆŒØŒÐÔ Ñ"ÐÔÐÐr   c                 ó    — | j                              t          |¦  «        ¦  «        }t          j                             | |d |…         ¦  «        S r   )r=   r   Úlenr   rT   Ú_writeSomeData)r   Údatar   s      r   rX   zShapedConsumer._writeSomeDataá   s>   € ð
 ”—’¥ T¡¤Ñ+Ô+ˆÝÔ(×7Ò7¸¸dÀ7ÀFÀ7¼mÑLÔLÐLr   c                 ón   — t           j                             | ¦  «         | j        xj        dz  c_        d S rE   )r   rT   ÚstopProducingr=   r&   )r   s    r   r[   zShapedConsumer.stopProducingé   s5   € ÝÔ!×/Ò/°Ñ5Ô5Ð5ØŒÐÔ Ñ"ÐÔÐÐr   N)r    r!   r"   r#   ÚiAmStreamingr   rX   r[   r'   r   r   rR   rR   Ó   sU   € € € € € ðð ð €Lð#ð #ð #ð
Mð Mð Mð#ð #ð #ð #ð #r   rR   c                   ó   — e Zd ZdZdZd„ ZdS )Ú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^   î   s4   € € € € € ðð ð €Lð,ð ,ð ,ð ,ð ,r   r^   c                   ó   — e Zd ZdZd„ Zd„ ZdS )Ú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                 ó"   — || _         || _        dS )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                 óL   ‡ ‡—  ‰ 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                 ón   •— ‰j                              | ¦  «        }t          | |¦  «        } ‰|¦  «        S r   )rg   r-   r^   )rI   r=   ÚshapedTransportÚorigMakeConnectionr   s      €€r   ÚmakeConnectionz6ShapedProtocolFactory.__call__.<locals>.makeConnection,  s9   ø€ ØÔ&×3Ò3°IÑ>Ô>ˆFÝ-¨i¸Ñ@Ô@ˆOØ%Ð% oÑ6Ô6Ð6r   )rf   rm   )r   r:   r;   Úprotorm   rl   s   `    @r   Ú__call__zShapedProtocolFactory.__call__!  sR   øø€ ð �”˜qÐ' BÐ'Ð'ˆØ"Ô1Ðð	7ð 	7ð 	7ð 	7ð 	7ð 	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Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1à !Ð !Ð !Ð !Ð !Ð !ðO!ð O!ð O!ð O!ð O!ñ O!ô O!ð O!ðdð ð ð ð �Iñ ô ð ð €ˆ]ÑÔð@ ð @ ð @ ð @ ð @ ñ @ ô @ ñ Ôð@ ðF&ð &ð &ð &ð &Ð+ñ &ô &ð &ð&ð &ð &ð &ð &Ð-ñ &ô &ð &ð#ð #ð #ð #ð #�SÔ.ñ #ô #ð #ð6,ð ,ð ,ð ,ð ,�nñ ,ô ,ð ,ð(0ð 0ð 0ð 0ð 0ñ 0ô 0ð 0ð 0ð 0r   