
    \d$                     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     5lib/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     			= IIFDMDL$@AAI()--i88I	!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DLL&&Cdm+I#di/Kq$,"<==DLDM|q  r   N)__name__
__module____qualname____doc__r
   r   int__annotations__r   	_refcountr   r   r    r   r   r	   r	      s           #Hhsm"""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     *VVdn$(:::JJLLL 	 94,9$IIIIbIILLLd)b))!!#&&>''55F &DL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_      <--// 	& 	&KC$kkmmO 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#'M8C='''       
  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d7F7m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3I>>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   