U
    ){f>                     @   s   d Z ddlZddlmZmZmZ G dd deZG dd deZG dd	 d	eZ	G d
d deZ
G dd deeZG dd deZG dd deZG dd deZG dd dZeeedddZG dd dZdS )zR
priority/tree
~~~~~~~~~~~~~

Implementation of the Priority tree data structure.
    N)ListTupleOptionalc                   @   s   e Zd ZdZdS )PriorityErrorz9
    The base class for all ``priority`` exceptions.
    N__name__
__module____qualname____doc__ r   r   P/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/priority/priority.pyr      s   r   c                   @   s   e Zd ZdZdS )DeadlockErrorz_
    Raised when there are no streams that can make progress: all streams are
    blocked.
    Nr   r   r   r   r   r      s   r   c                   @   s   e Zd ZdZdS )PriorityLoopzM
    An unexpected priority loop has been detected. The tree is invalid.
    Nr   r   r   r   r   r      s   r   c                   @   s   e Zd ZdZdS )DuplicateStreamErrorzE
    An attempt was made to insert a stream that already exists.
    Nr   r   r   r   r   r   %   s   r   c                   @   s   e Zd ZdZdS )MissingStreamErrorzQ
    An operation was attempted on a stream that is not present in the tree.
    Nr   r   r   r   r   r   -   s   r   c                   @   s   e Zd ZdZdS )TooManyStreamsErrorz
    An attempt was made to insert a dangerous number of streams into the
    priority tree at the same time.

    .. versionadded:: 1.2.0
    Nr   r   r   r   r   r   5   s   r   c                   @   s   e Zd ZdZdS )BadWeightErrorze
    An attempt was made to create a stream with an invalid weight.

    .. versionadded:: 1.3.0
    Nr   r   r   r   r   r   @   s   r   c                   @   s   e Zd ZdZdS )PseudoStreamErrorzN
    An operation was attempted on stream 0.

    .. versionadded:: 1.3.0
    Nr   r   r   r   r   r   J   s   r   c                   @   s   e Zd ZdZd&eeddddZeeddd	Zejedd
dd	Zd ddddZ	d ddddZ
d'd eddddZedddZedddZeedddZeedddZd edddZd edd d!Zd edd"d#Zd edd$d%ZdS )(Streamz
    Priority information for a given stream.

    :param stream_id: The stream ID for the new stream.
    :param weight: (optional) The stream weight. Defaults to 16.
       N)	stream_idweightreturnc                 C   s4   || _ || _g | _d | _g | _d| _d| _d| _d S )NTr   )r   r   childrenparentchild_queueactivelast_weight_deficit)selfr   r   r   r   r   __init__\   s    zStream.__init__r   c                 C   s   | j S N)_weightr   r   r   r   r   f   s    zStream.weight)valuer   c                 C   s<   t |tstdnd|  kr(dks2n td|| _d S )Nz"Stream weight should be an integer      z3Stream weight must be between 1 and 256 (inclusive))
isinstanceintr   r#   )r   r%   r   r   r   r   j   s
    

)childr   c                 C   s*   | |_ | j| t| j| j|f dS )z}
        Add a stream that depends on this one.

        :param child: A ``Stream`` object that depends on this one.
        N)r   r   appendheapqheappushr   r   )r   r*   r   r   r   	add_childt   s    zStream.add_childc                 C   s:   | j }g | _ g | _d| _| | |D ]}|| q&dS )z
        Add a stream that exclusively depends on this one.

        :param child: A ``Stream`` object that exclusively depends on this one.
        r   N)r   r   r   r.   )r   r*   Zold_childrenZ	old_childr   r   r   add_child_exclusive~   s    
zStream.add_child_exclusiveT)r*   strip_childrenr   c                 C   sf   | j | g }| jrBt| j\}}||kr0qt|||f q|| _|rb|j D ]}| | qRdS )a"  
        Removes a child stream from this stream. This is a potentially somewhat
        expensive operation.

        :param child: The child stream to remove.
        :param strip_children: Whether children of the removed stream should
            become children of this stream.
        N)r   remover   r,   heappopr-   r.   )r   r*   r0   Z	new_queuelevelstream	new_childr   r   r   remove_child   s    
zStream.remove_childc                 C   s   | j r
td}g }z`|dkrpt| j}|	| |\}}|j rH|j
}qz| }W q tk
rl   Y qY qX qW 5 |D ]F\}}|| _|d|j |j 7 }d|j |j |_t| j||f qxX |S )z
        Returns the stream ID of the next child to schedule. Potentially
        recurses down the tree of priorities.
        Nr'   )r   AssertionErrorr   r   r   r,   r-   r   r2   r+   r   schedule
IndexError)r   Znext_streamZpopped_streamsr3   r*   valr   r   r   r8      s(    

zStream.schedulec                 C   s   d| j | jf S )NzStream<id=%d, weight=%d>r   r   r$   r   r   r   __repr__   s    zStream.__repr__)otherr   c                 C   s   t |tsdS | j|jkS )NF)r(   r   r   r   r=   r   r   r   __eq__   s    
zStream.__eq__c                 C   s   |  | S r"   )r?   r>   r   r   r   __ne__   s    zStream.__ne__c                 C   s   t |tstS | j|jk S r"   r(   r   NotImplementedr   r>   r   r   r   __lt__   s    
zStream.__lt__c                 C   s   t |tstS | j|jkS r"   rA   r>   r   r   r   __le__   s    
zStream.__le__c                 C   s   t |tstS | j|jkS r"   rA   r>   r   r   r   __gt__   s    
zStream.__gt__c                 C   s   t |tstS | j|jkS r"   rA   r>   r   r   r   __ge__   s    
zStream.__ge__)r   )T)r   r   r	   r
   r)   r    propertyr   setterr.   r/   boolr6   r8   strr<   objectr?   r@   rC   rD   rE   rF   r   r   r   r   r   T   s,   
	
 #(r   )
new_parentcurrentr   c                 C   sL   | }t dD ],}|j}|j|jkr( dS |jdkr dS qtd| j dS )zG
    Reports whether the new parent depends on the current stream.
    d   Tr   Fz Stream %d is in a priority loop.N)ranger   r   r   )rL   rM   r   _r   r   r   _stream_cycle   s    
rQ   c                   @   s   e Zd ZdZd"eddddZeeddd	Zeedd
ddZd#ee	e ee
ddddZd$ee	e ee
ddddZeddddZeddddZeddddZd dddZedddZedd d!ZdS )%PriorityTreea  
    A HTTP/2 Priority Tree.

    This tree stores HTTP/2 streams according to their HTTP/2 priorities.

    .. versionchanged:: 1.2.0
       Added ``maximum_streams`` keyword argument.

    :param maximum_streams: The maximum number of streams that may be active in
        the priority tree at any one time. If this number is exceeded, the
        priority tree will raise a :class:`TooManyStreamsError
        <priority.TooManyStreamsError>` and will refuse to insert the stream.

        This parameter exists to defend against the possibility of DoS attack
        by attempting to overfill the priority tree. If any endpoint is
        attempting to manage the priority of this many streams at once it is
        probably trying to screw with you, so it is sensible to simply refuse
        to play ball at that point.

        While we allow the user to configure this, we don't really *expect*
        them too, unless they want to be even more conservative than we are by
        default.
    :type maximum_streams: ``int``
      N)maximum_streamsr   c                 C   sN   t ddd| _d| j_d| ji| _t|ts4td|dkrDtd|| _d S )Nr   r&   r;   Fzmaximum_streams must be an int.z+maximum_streams must be a positive integer.)	r   _root_streamr   _streamsr(   r)   	TypeError
ValueError_maximum_streams)r   rT   r   r   r   r    -  s    
zPriorityTree.__init__)parent_stream_idr   c                 C   sD   z| j | W S  tk
r>   | | | | | j |  Y S X dS )a*  
        When inserting or reprioritizing a stream it is possible to make it
        dependent on a stream that is no longer in the tree. In this situation,
        rather than bail out, we should insert the parent stream into the tree
        with default priority and mark it as blocked.
        N)rV   KeyErrorinsert_streamblock)r   rZ   r   r   r   _get_or_insert_parent:  s    

z"PriorityTree._get_or_insert_parent)parent_streaminserted_streamr   c                 C   s   | | dS )z}
        Insert ``inserted_stream`` beneath ``parent_stream``, obeying the
        semantics of exclusive insertion.
        N)r/   )r   r_   r`   r   r   r   _exclusive_insertH  s    	zPriorityTree._exclusive_insertr   F)r   
depends_onr   	exclusiver   c                 C   s   || j krtd| t| j d | jkr<td| jd  t||}|sPd}n||krdtd| |r| |}| || || j |< dS | |}|	| || j |< dS )a  
        Insert a stream into the tree.

        :param stream_id: The stream ID of the stream being inserted.
        :param depends_on: (optional) The ID of the stream that the new stream
            depends on, if any.
        :param weight: (optional) The weight to give the new stream. Defaults
            to 16.
        :param exclusive: (optional) Whether this new stream should be an
            exclusive dependency of the parent.
        zStream %d already in treer&   z8Refusing to insert %d streams into priority tree at oncer   z$Stream %d must not depend on itself.N)
rV   r   lenrY   r   r   r   r^   ra   r.   )r   r   rb   r   rc   r4   r_   r   r   r   r   r\   S  s*    





zPriorityTree.insert_streamc                 C   s   |dkrt dz| j| }W n  tk
r>   td| Y nX |rn||krXtd| | |}t||}n| jd }d}||_|r|j	| |j
| |jj	|dd |r|| n
|
| dS )a  
        Update the priority status of a stream already in the tree.

        :param stream_id: The stream ID of the stream being updated.
        :param depends_on: (optional) The ID of the stream that the stream now
            depends on. If ``None``, will be moved to depend on stream 0.
        :param weight: (optional) The new weight to give the stream. Defaults
            to 16.
        :param exclusive: (optional) Whether this stream should now be an
            exclusive dependency of the new parent.
        r   zCannot reprioritize stream 0Stream %d not in treez#Stream %d must not depend on itselfF)r0   N)r   rV   r[   r   r   r^   rQ   r   r   r6   r.   r/   )r   r   rb   r   rc   Zcurrent_streamrL   cycler   r   r   reprioritize  s8    

 zPriorityTree.reprioritize)r   r   c                 C   sV   |dkrt dz| j|}W n  tk
r@   td| Y nX |j}|| dS )zu
        Removes a stream from the priority tree.

        :param stream_id: The ID of the stream to remove.
        r   zCannot remove stream 0re   N)r   rV   popr[   r   r   r6   )r   r   r*   r   r   r   r   remove_stream  s    zPriorityTree.remove_streamc                 C   sF   |dkrt dzd| j| _W n  tk
r@   td| Y nX dS )z
        Marks a given stream as blocked, with no data to send.

        :param stream_id: The ID of the stream to block.
        r   zCannot block stream 0Fre   Nr   rV   r   r[   r   r   r   r   r   r   r]     s    zPriorityTree.blockc                 C   sF   |dkrt dzd| j| _W n  tk
r@   td| Y nX dS )z
        Marks a given stream as unblocked, with more data to send.

        :param stream_id: The ID of the stream to unblock.
        r   zCannot unblock stream 0Tre   Nrj   rk   r   r   r   unblock  s    zPriorityTree.unblockr!   c                 C   s   | S r"   r   r$   r   r   r   __iter__  s    zPriorityTree.__iter__c                 C   s.   z| j  W S  tk
r(   tdY nX d S )Nz!No unblocked streams to schedule.)rU   r8   r9   r   r$   r   r   r   __next__  s    zPriorityTree.__next__c                 C   s   |   S r"   )rn   r$   r   r   r   next  s    zPriorityTree.next)rS   )Nr   F)Nr   F)r   r   r	   r
   r)   r    r   r^   ra   r   rI   r\   rg   ri   r]   rl   rm   rn   ro   r   r   r   r   rR     sB      /   ?rR   )r
   r,   typingr   r   r   	Exceptionr   r   r   r   r[   r   r   r   r   r   rI   rQ   rR   r   r   r   r   <module>   s   	

 +