o
    h%x                  	   @   sz  d Z ddlmZmZ ddlmZmZmZmZm	Z	m
Z
mZ dZe
dZG dd dee Ze
ded	Zd
edefddZd
edefddZG dd dZG dd deeef ZG dd deeef ZG dd deZG dd deeef Ze
dZG dd deeeef ZG dd deeef eeeeef f eeef ZG dd  d eee ZG d!d" d"eee ee Zd#S )$z
A BTree in the style of Cormen, Leiserson, and Rivest's "Algorithms" book, with
copy-on-write node updates, cursors, and optional space optimization for mostly-in-order
insertion.
    )MutableMapping
MutableSet)AnyCallableGenericOptionalTupleTypeVarcast   KTc                   @   s   e Zd ZdZdefddZdS )Elementz+All items stored in the BTree are Elements.returnc                 C   s   t )zFThe key for this element; the returned type must implement comparison.)NotImplementedErrorself r   K/var/www/html/pro-man-master/venv/lib/python3.10/site-packages/dns/btree.pykey   s   zElement.keyN)__name__
__module____qualname____doc__r   r   r   r   r   r   r      s    r   ET)boundtr   c                 C   s   | d S )z[The minimum number of keys in a non-root node for a BTree with the specified
    ``t``
       r   r   r   r   r   _MIN   s   r   c                 C   s   d|  d S )zGThe maximum number of keys in node for a BTree with the specified ``t``   r   r   r   r   r   r   _MAX#   s   r    c                   @   s   e Zd ZdZdd ZdS )_CreatorzA _Creator class instance is used as a unique id for the BTree which created
    a node.

    We use a dedicated creator rather than just a BTree reference to avoid circularity
    that would complicate GC.
    c                 C   s   t | dS )Nxidr   r   r   r   __str__0      z_Creator.__str__N)r   r   r   r   r%   r   r   r   r   r!   (   s    r!   c                	   @   s
  e Zd ZdZg dZdededefddZdefd	d
Z	defddZ
dedeeef fddZdeddfddZdedeed ef fddZdededB fddZdeddfddZdedededB fddZdededf fdd Zd!ddedefd"d#Zd!ddedefd$d%Zd&dd'ed(dddfd)d*Zd!ddeddfd+d,Zdefd-d.Zdefd/d0Zd!ddeddfd1d2Zded!ed d3edB dedB fd4d5Zd6eegdf ddfd7d8Z d6edgdf ddfd9d:Z!deded fd;d<Z"deddfd=d>Z#d?d@ Z$dS )A_NodezFA Node in the BTree.

    A Node (leaf or internal) of the BTree.
    r   creatoris_leafeltschildrenr   r)   r*   c                 C   s.   |dksJ || _ || _|| _g | _g | _d S )N   r(   )r   r   r)   r*   r   r   r   __init__<   s   
z_Node.__init__r   c                 C   s,   t | jt| jksJ t | jt| jkS )z/Does this node have the maximal number of keys?)lenr+   r    r   r   r   r   r   
is_maximalD      z_Node.is_maximalc                 C   s,   t | jt| jksJ t | jt| jkS )z/Does this node have the minimal number of keys?)r/   r+   r   r   r   r   r   r   
is_minimalI   r1   z_Node.is_minimalr   c                 C   s   t | j}|dkr|| j|d   kr|dfS d}t | j}|d }d}||krV|| d }| j|  }||krC|}d}	 ||fS ||k rN|}|d }n|d }||ks)||fS )zGet the index of the ``Element`` matching ``key`` or the index of its
        least successor.

        Returns a tuple of the index and an ``equal`` boolean that is ``True`` iff.
        the key was found.
        r   r   Fr   T)r/   r+   r   )r   r   lirequalmkr   r   r   search_in_nodeN   s*   


z_Node.search_in_nodeindexz_Node[KT, ET]c                 C   s6   | j rJ | j| }|| j}|r|| j|< |S |S N)r*   r,   	maybe_cowr)   )r   r:   childclonedr   r   r   maybe_cow_childk   s   


z_Node.maybe_cow_childc                 C   s8   |  |\}}|r| |fS | jrdS | |}||S )zGet the node associated with key and its index, doing
        copy-on-write if we have to descend.

        Returns a tuple of the node and the index, or the tuple ``(None, 0)``
        if the key was not found.
        Nr   )r9   r*   r?   	_get_node)r   r   r4   r6   r=   r   r   r   rA   u   s   

z_Node._get_nodeNc                 C   s6   |  |\}}|r| j| S | jrdS | j| |S )z8Get the element associated with *key* or return ``None``N)r9   r+   r*   r,   get)r   r   r4   r6   r   r   r   rB      s   
z	_Node.getc                 C   s   |dkrdS | j |d  }t|jt| jkrdS | |d }t|jt| jk r@|| |d s4dS t|jt| jk s*dS dS )a-  Try to minimize the number of Nodes in a BTree where the insertion
        is done in-order or close to it, by stealing as much as we can from our
        right sibling.

        If we don't do this, then an in-order insertion will produce a BTree
        where most of the nodes are minimal.
        r   Nr   )r,   r/   r+   r    r   r?   try_right_steal)r   r:   leftr   r   r   optimize_in_order_insertion   s   z!_Node.optimize_in_order_insertionelementin_orderc           	      C   s   |   rJ 	 | }| |\}}|r | j| }|| j|< |S | jr,| j|| d S | |}|  r=| j|   q|	||}|rJ| 
| |S r;   )r0   r   r9   r+   r*   insertr?   adoptsplitinsert_nonfullrE   )	r   rF   rG   r   r4   r6   oldr=   oeltr   r   r   rK      s&   



z_Node.insert_nonfullc                 C   s   |   sJ | | j| j| j}t| jt| jd d |_| jt| j }t| jdt| j | _| jsUt| jt| jd d |_t| jdt| jd  | _| ||fS )zASplit a maximal node into two minimal ones and a central element.r   N)	r0   	__class__r   r)   r*   listr+   r   r,   )r   rightmiddler   r   r   rJ      s   
z_Node.splitparentc                 C   s   |dkrD|j |d  }| sD||d }|j|d  }|j |j|d < | jd| |jsB| jr6J |j  }| j d| dS dS )zTry to steal from this Node's left sibling for balancing purposes.

        Returns ``True`` if the theft was successful, or ``False`` if not.
        r   r   TF)r,   r2   r?   r+   poprH   r*   )r   rR   r:   rD   eltr=   r   r   r   try_left_steal   s   

z_Node.try_left_stealc                 C   s   |d t |jk rE|j|d  }| sE||d }|j| }|jd|j|< | j| |jsC| jr7J |jd}| j| dS dS )zTry to steal from this Node's right sibling for balancing purposes.

        Returns ``True`` if the theft was successful, or ``False`` if not.
        r   r   TF)r/   r,   r2   r?   r+   rS   appendr*   )r   rR   r:   rP   rT   r=   r   r   r   rC      s   

z_Node.try_right_stealrD   rQ   rP   c                 C   s   |   rJ | jrJ | }| |\}}|rJ | j|| t| jdkr/||g| _dS | j| |ks8J | j|d | dS )zAdopt left, middle, and right into our Node (which must not be maximal,
        and which must not be a leaf).  In the case were we are not the new root,
        then the left child must already be in the Node.r   r   N)r0   r*   r   r9   r+   rH   r/   r,   )r   rD   rQ   rP   r   r4   r6   r   r   r   rI      s   
z_Node.adoptc                 C   sN   |j |d }| j|j| | j|j | js%| j |j  dS dS )z>Merge this node's parent and its right sibling into this node.r   N)r,   rS   r+   rV   extendr*   )r   rR   r:   rP   r   r   r   merge   s   z_Node.mergec                 C      | j r| jd S | jd  S )z"The least element in this subtree.r   )r*   r+   r,   minimumr   r   r   r   rZ        
z_Node.minimumc                 C   rY   )z%The greatest element in this subtree.)r*   r+   r,   maximumr   r   r   r   r]     r[   z_Node.maximumc                 C   sd   |j rJ | ||rdS | ||rdS |dkr!| || dS ||d }|||d  dS )zThis Node is minimal, and we want to make it non-minimal so we can delete.
        We try to steal from our siblings, and if that doesn't work we will merge
        with one of them.Nr   r   )r*   rU   rC   rX   r?   )r   rR   r:   rD   r   r   r   balance  s   
z_Node.balanceexactc                 C   s@  |du s
|   r
J | |\}}d}|rB|dur$| j| |ur$td| jr-| j|S d}|}| j|d   }| }|d }| jrO|durMtddS | 	|}|  rt|
| | | |\}}|riJ | j| }|  rtJ ||| |}	|dur| |\}
}|
dusJ |	dusJ |
j| }|	|
j|< |}	|	S )zDelete an element matching *key* if it exists.  If *exact* is not ``None``
        then it must be an exact match with that element.  The Node must not be
        minimal unless it is the root.Nz'exact delete did not match existing eltr   zexact delete had no match)r2   r9   r+   
ValueErrorr*   rS   r,   rZ   r   r?   r^   deleterA   )r   r   rR   r_   r4   r6   original_keyleast_successorr=   rT   noderM   r   r   r   ra   &  sB   



z_Node.deletevisitc                 C   sP   t | jD ]\}}| js| j| | || q| js&| jd | dS dS )z-Call *visit* on all of the elements in order.r\   N)	enumerater+   r*   r,   visit_in_order)r   re   r4   rT   r   r   r   rg   U  s   
z_Node.visit_in_orderc                 C   s,   ||  | j s| jD ]	}|| q
dS dS )z?Visit nodes in preorder.  This method is only used for testing.N)r*   r,   _visit_preorder_by_node)r   re   r=   r   r   r   rh   ^  s   
z_Node._visit_preorder_by_nodec                 C   s   | j |ur
| |S dS )zReturn a clone of this Node if it was not created by *creator*, or ``None``
        otherwise (i.e. copy for copy-on-write if we haven't already copied it).N)r)   clone)r   r)   r   r   r   r<   e  s   

z_Node.maybe_cowc                 C   s8   |  | j|| j}|j| j | js|j| j |S )z+Make a shallow-copy duplicate of this node.)rN   r   r*   r+   rW   r,   )r   r)   r>   r   r   r   ri   m  s
   z_Node.clonec                 C   sH   | j sdddd | jD  }nd}t| dd| j d| j | S )N c                 S   s   g | ]}t |d qS )r"   r#   ).0cr   r   r   
<listcomp>w  s    z!_Node.__str__.<locals>.<listcomp> r"   )r*   joinr,   r$   r)   r+   )r   r,   r   r   r   r%   u  s   "z_Node.__str__)%r   r   r   r   	__slots__intr!   boolr.   r0   r2   r   tupler9   r?   r   r   rA   r   rB   rE   rK   rJ   rU   rC   rI   rX   rZ   r]   r^   ra   r   rg   rh   r<   ri   r%   r   r   r   r   r'   4   sD    


/	r'   c                   @   s   e Zd ZdZd$ddZd%dd	Zd%d
dZdd Zdd Zde	dB fddZ
de	dB fddZdededdfddZd&dededdfddZd%ddZd%ddZd d! Zd"d# ZdS )'CursorzA seekable cursor for a BTree.

    If you are going to use a cursor on a mutable BTree, you should use it
    in a ``with`` block so that any mutations of the BTree automatically park
    the cursor.
    btreeBTree[KT, ET]c                 C   s:   || _ d | _d| _d| _d| _g | _d| _d | _d| _d S )Nr   FT)	ru   current_nodecurrent_indexrecurse
increasingparentsparkedparking_keyparking_key_read)r   ru   r   r   r   r.     s   
zCursor.__init__r   Nc                 C   s^   | j d usJ | j js-| j| j | jf | j j| j | _ | j d us$J d| _| j jrd S d S r@   )rw   r*   r{   rV   rx   r,   r   r   r   r   _seek_least  s   zCursor._seek_leastc                 C   sf   | j d usJ | j js1| j| j | jf | j j| j | _ | j d us$J t| j j| _| j jrd S d S r;   )rw   r*   r{   rV   rx   r,   r/   r+   r   r   r   r   _seek_greatest  s   zCursor._seek_greatestc                 C      | j sd| _ dS dS )a  Park the cursor.

        A cursor must be "parked" before mutating the BTree to avoid undefined behavior.
        Cursors created in a ``with`` block register with their BTree and will park
        automatically.  Note that a parked cursor may not observe some changes made when
        it is parked; for example a cursor being iterated with next() will not see items
        inserted before its current position.
        TN)r|   r   r   r   r   park  s   	
zCursor.parkc                 C   sT   | j r(| jd ur | j}| jr| j }n| j}| | j| || _d| _ d | _d S d S NF)r|   r}   rz   r~   seek)r   rz   beforer   r   r   _maybe_unpark  s   


zCursor._maybe_unparkc                 C   s   |    d| _| jdu r+| jdkrdS | jdksJ | jj| _t| jjj| _|   	 | j	r9| j
s6|   d| _	d| _
|  jd8  _| jdkr`| jj| j }| jjsVd| _	| | _d| _|S t| jdkrq| j \| _| _nd| _d| _dS q,)zAGet the previous element, or return None if on the left boundary.Nr   r   TF)r   r}   rw   rx   ru   rootr/   r+   r   ry   rz   r*   r   r~   r{   rS   r   rT   r   r   r   prev  s:   




zCursor.prevc                 C   s   |    d| _| jdu r&| jdkrdS | jdksJ | jj| _d| _|   	 | jr4| jr1|   d| _d| _| jt	| jj
k r_| jj
| j }|  jd7  _| jjsUd| _| | _d| _|S t	| jdkrp| j \| _| _nd| _d| _dS q')z>Get the next element, or return None if on the right boundary.Nr   r   TF)r   r}   rw   rx   ru   r   r   ry   rz   r/   r+   r*   r   r~   r{   rS   r   r   r   r   next  s:   



zCursor.nextr   r4   c                 C   s   |r|| _ d S |d | _ d S )Nr   )rx   )r   r   r4   r   r   r   _adjust_for_before  s   
zCursor._adjust_for_beforeTr   c                 C   s   | j j| _| jdusJ d| _g | _|| _d| _|| _d| _| jj	s[| j
|\}}|r@| || |r:|   dS |   dS | j| j|f | jj| | _| jdusWJ | jj	r"| j
|\}}|rm| || dS || _dS )a  Seek to the specified key.

        If *before* is ``True`` (the default) then the cursor is positioned just
        before *key* if it exists, or before its least successor if it doesn't.  A
        subsequent next() will retrieve this value.  If *before* is ``False``, then
        the cursor is positioned just after *key* if it exists, or its greatest
        precessessor if it doesn't.  A subsequent prev() will return this value.
        NF)ru   r   rw   ry   r{   rz   r|   r}   r~   r*   r9   r   r   r   rV   r,   rx   )r   r   r   r4   r6   r   r   r   r     s2   
	
zCursor.seekc                 C   s.   d| _ d| _d| _d| _g | _d| _d| _dS )zSeek to the left boundary (i.e. just before the least element).

        A subsequent next() will return the least element if the BTree isn't empty.Nr   FTrw   rx   ry   rz   r{   r|   r}   r   r   r   r   
seek_first?  s   
zCursor.seek_firstc                 C   s.   d| _ d| _d| _d| _g | _d| _d| _dS )zSeek to the right boundary (i.e. just after the greatest element).

        A subsequent prev() will return the greatest element if the BTree isn't empty.
        Nr   Fr   r   r   r   r   	seek_lastK  s   
zCursor.seek_lastc                 C   s   | j |  | S r;   )ru   register_cursorr   r   r   r   	__enter__X     zCursor.__enter__c                 C   s   | j |  dS r   )ru   deregister_cursor)r   exc_type	exc_value	tracebackr   r   r   __exit__\  r   zCursor.__exit__)ru   rv   r   N)T)r   r   r   r   r.   r   r   r   r   r   r   r   rr   rq   r   r   r   r   r   r   r   r   r   r   r   rt   }  s    




((
#
rt   c                   @   s   e Zd ZdZdS )	ImmutablezThe BTree is immutable.N)r   r   r   r   r   r   r   r   r   a  s    r   c                   @   sF  e Zd ZdZedddeded  fddZdd	 Zd/ddZ	d0de
ded
e
dB fddZded
e
dB fddZdede
dB d
e
dB fddZded
e
dB fddZde
d
e
dB fddZdd Zdee
gdf d
dfd d!Zdeegdf d
dfd"d#Zd
eee
f fd$d%Zd&ed
dfd'd(Zd&ed
dfd)d*Zd+d, Zd-d. ZdS )1BTreez2An in-memory BTree with copy-on-write and cursors.Nr   originalr   r   c                C   s   t  | _d| _|  |  |  t | _|dur*|jstd|j| _|j| _|j| _dS |dk r2td|| _t	| j| jd| _d| _dS )zCreate a BTree.

        If *original* is not ``None``, then the BTree is shallow-cloned from
        *original* using copy-on-write.  Otherwise a new BTree with the specified
        *t* value is created.

        The BTree is not thread-safe.
        FNzoriginal BTree is not immutabler-   zt must be >= 3Tr   )
r!   r)   
_immutablesetcursorsr`   r   r   sizer'   )r   r   r   r   r   r   r.   h  s"   
zBTree.__init__c                 C   r   )zMake the BTree immutable.

        Attempts to alter the BTree after making it immutable will raise an
        Immutable exception.  This operation cannot be undone.
        TN)r   r   r   r   r   make_immutable  s   
zBTree.make_immutabler   c                 C   s"   | j rt| jD ]}|  qd S r;   )r   r   r   r   r   cursorr   r   r   _check_mutable_and_park  s
   

zBTree._check_mutable_and_parkFrT   rG   c                 C   sz   |    | j| j}|r|| _| j r)| j}t| j| jd| _| jj|   | j	||}|du r;|  j
d7  _
|S )aE  Insert the element into the BTree.

        If *in_order* is ``True``, then extra work will be done to make left siblings
        full, which optimizes storage space when the the elements are inserted in-order
        or close to it.

        Returns the previously existing element at the element's key or ``None``.
        FNr   )r   r   r<   r)   r0   r'   r   rI   rJ   rK   r   )r   rT   rG   r>   old_rootrM   r   r   r   insert_element  s   	
zBTree.insert_elementr   c                 C   s   | j |S )zhGet the element matching *key* from the BTree, or return ``None`` if it
        does not exist.
        )r   rB   r   r   r   r   r   get_element  s   zBTree.get_elementr_   c                 C   s   |    | j| j}|r|| _| j|d |}|d ur@|  jd8  _t| jjdkr@| jjs@t| jj	dks9J | jj	d | _|S )Nr   r   )
r   r   r<   r)   ra   r   r/   r+   r*   r,   )r   r   r_   r>   rT   r   r   r   _delete  s   zBTree._deletec                 C   s   |  |dS )zDelete the element matching *key* from the BTree.

        Returns the matching element or ``None`` if it does not exist.
        N)r   r   r   r   r   
delete_key  s   zBTree.delete_keyrF   c                 C   s    |  | |}||u sJ |S )zwDelete *element* from the BTree.

        Returns the matching element or ``None`` if it was not in the BTree.
        )r   r   )r   rF   deltr   r   r   delete_exact  s   zBTree.delete_exactc                 C      | j S r;   )r   r   r   r   r   __len__     zBTree.__len__re   c                 C      | j | dS )zBCall *visit*(element) on all elements in the tree in sorted order.N)r   rg   r   re   r   r   r   rg        zBTree.visit_in_orderc                 C   s   | j | d S r;   )r   rh   r   r   r   r   rh     s   zBTree._visit_preorder_by_nodec                 C   s   t | S )zCreate a cursor.)rt   r   r   r   r   r     s   zBTree.cursorr   c                 C   r   )z4Register a cursor for the automatic parking service.N)r   addr   r   r   r   r     r   zBTree.register_cursorc                 C   r   )z7Deregister a cursor from the automatic parking service.N)r   discardr   r   r   r   r     r   zBTree.deregister_cursorc                 C   s   | j | dS )N)r   rN   r   r   r   r   __copy__  r&   zBTree.__copy__c                 c   sP    |   }	 | }|d u rn| V  qW d    d S 1 s!w   Y  d S r;   )r   r   r   )r   r   rT   r   r   r   __iter__  s   

"zBTree.__iter__r   )F)r   r   r   r   	DEFAULT_Trq   r   r.   r   r   r   rr   r   r   r   r   r   r   r   r   rg   r'   rh   rt   r   r   r   r   r   r   r   r   r   r   e  s$    
	
	r   VTc                   @   sN   e Zd ZdZdedefddZdefddZdefd	d
Zdd Z	dd Z
dS )KVz/The BTree element type used in a ``BTreeDict``.r   valuec                 C   s   || _ || _d S r;   _key_value)r   r   r   r   r   r   r.     s   
zKV.__init__r   c                 C   r   r;   r   r   r   r   r   r     r   zKV.keyc                 C   r   r;   )r   r   r   r   r   r     r   zKV.valuec                 C      d| j  d| j dS NzKV(z, )r   r   r   r   r   r%   	     z
KV.__str__c                 C   r   r   r   r   r   r   r   __repr__  r   zKV.__repr__N)r   r   r   r   r   r   r.   r   r   r%   r   r   r   r   r   r     s    r   c                       sv   e Zd ZdZeddddededB def fdd	Zd
e	de
fddZd
e	de
ddfddZd
e	ddfddZ  ZS )	BTreeDictzA MutableMapping implemented with a BTree.

    Unlike a normal Python dict, the BTreeDict may be mutated while iterating.
    NFr   r   rG   r   r   rG   c                      t  j||d || _d S Nr   superr.   rG   r   r   r   rG   r   r   r   r.        
zBTreeDict.__init__r   r   c                 C   s$   |  |}|d u rttt| S r;   )r   KeyErrorr
   r   r   )r   r   rT   r   r   r   __getitem__   s   
zBTreeDict.__getitem__r   c                 C   s   t ||}| || j d S r;   )r   r   rG   )r   r   r   rT   r   r   r   __setitem__'  s   
zBTreeDict.__setitem__c                 C   s   |  |d u r	td S r;   )r   r   r   r   r   r   __delitem__+  s   zBTreeDict.__delitem__)r   r   r   r   r   rq   r   rr   r.   r   r   r   r   r   __classcell__r   r   r   r   r     s    
r   c                   @   s,   e Zd ZdZdefddZdefddZdS )	Memberz.The BTree element type used in a ``BTreeSet``.r   c                 C   s
   || _ d S r;   r   r   r   r   r   r.   3  s   
zMember.__init__r   c                 C   r   r;   r   r   r   r   r   r   6  r   z
Member.keyN)r   r   r   r   r   r.   r   r   r   r   r   r   0  s    r   c                       sr   e Zd ZdZeddddededB def fdd	Zd
e	defddZ
deddfddZdeddfddZ  ZS )BTreeSetzyA MutableSet implemented with a BTree.

    Unlike a normal Python set, the BTreeSet may be mutated while iterating.
    NFr   r   r   rG   c                   r   r   r   r   r   r   r   r.   @  r   zBTreeSet.__init__r   r   c                 C   s   |  |d uS r;   )r   r   r   r   r   __contains__J     zBTreeSet.__contains__r   c                 C   s   t |}| || j d S r;   )r   r   rG   )r   r   rT   r   r   r   r   M  s   zBTreeSet.addc                 C   s   |  | d S r;   )r   )r   r   r   r   r   r   Q  r   zBTreeSet.discard)r   r   r   r   r   rq   r   rr   r.   r   r   r   r   r   r   r   r   r   r   r   :  s    
r   N)r   collections.abcr   r   typingr   r   r   r   r   r	   r
   r   r   r   r   rq   r   r    r!   r'   rt   	Exceptionr   r   r   r   r   r   r   r   r   r   r   <module>   s.   $  K e 4  
