a
    
d߂                     @   sd   d Z ddlZddlmZ eddZdZdZdZed	d
Z	eddZ
dd Zdd Zdd ZdS )z
Timsort implementation.  Mostly adapted from CPython's listobject.c.

For more information, see listsort.txt in CPython's source tree.
    N)typesTimsortImplementation)compile	count_run
binarysortgallop_leftgallop_right
merge_initmerge_append	merge_popmerge_compute_minrunmerge_lomerge_himerge_atmerge_force_collapsemerge_collapserun_timsortrun_timsort_with_valuesU         
MergeState)
min_gallopkeysvaluespendingnMergeRun)startsizec                    s  | t jd| dd | fdd| fdd| dd	 
| d
d | fdd| fdd	| dd | fdd| fdd| fdd| fdd| dd | fdd| fddd  |  	fd!d"|  	f	d#d$| fd%d&| fd'd(| fd)d*| fd+d,| 
fd-d.| fd/d0}| fd1d2}t| 
||S )3Nr   c                 S   s   || uS N r   r   r!   r!   [/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/numba/misc/timsort.py
has_values?   s    z%make_timsort_impl.<locals>.has_valuesc                    sH   t t| d d t}| |}|}tgt }t t|||S )z?
        Initialize a MergeState for a non-keyed sort.
              minlenMERGESTATE_TEMP_SIZEr   MAX_MERGE_PENDINGr   
MIN_GALLOP)r   	temp_size	temp_keystemp_valuesr   intpmake_temp_areazeror!   r#   r	   C   s
    
z%make_timsort_impl.<locals>.merge_initc                    sN   t t| d d t}| |}||}tgt }t t|||S )z;
        Initialize a MergeState for a keyed sort.
        r%   r&   r'   )r   r   r-   r.   r/   r   r0   r!   r#   merge_init_with_valuesN   s
    

z1make_timsort_impl.<locals>.merge_init_with_valuesc                 S   s8   | j }|tk sJ || j|< t| j| j| j| j|d S )z2
        Append a run on the merge stack.
        r&   )r   r+   r   r   r   r   r   )msrunr   r!   r!   r#   r
   Y   s    
z'make_timsort_impl.<locals>.merge_appendc                 S   s   t | j| j| j| j| jd S )z7
        Pop the top run from the merge stack.
        r&   )r   r   r   r   r   r   )r5   r!   r!   r#   r   c   s    z$make_timsort_impl.<locals>.merge_popc                    sj   t | j}||kr| S ||k r(|d> }q| j|} | j| jrP| j|}n|}t| j||| j| jS )zJ
        Ensure enough temp memory for 'need' items is available.
        r&   )r)   r   r   r   r   r   r   )r5   ZneedZallocedr.   r/   )r$   r2   r!   r#   merge_getmemj   s    

z'make_timsort_impl.<locals>.merge_getmemc                    s   t  || j| j| j| jS )z5
        Modify the MergeState's min_gallop.
        )r   r   r   r   r   )r5   Z
new_gallop)r1   r!   r#   merge_adjust_gallop~   s    z.make_timsort_impl.<locals>.merge_adjust_gallopc                 S   s   | |k S )z
        Trivial comparison function between two keys.  This is factored out to
        make it clear where comparisons occur.
        r!   )abr!   r!   r#   LT   s    zmake_timsort_impl.<locals>.LTc                    s   ||kr||ksJ | |}||kr.|d7 }||k r| | }|}|}||k r|||| d?  }	 || |	 rr|	}qF|	d }qFt ||dD ]}	| |	d  | |	< q|| |< |r|| }
t ||dD ]}	||	d  ||	< q|
||< |d7 }q.dS )a  
        binarysort is the best method for sorting small arrays: it does
        few compares, but can do data movement quadratic in the number of
        elements.
        [lo, hi) is a contiguous slice of a list, and is sorted via
        binary insertion.  This sort is stable.
        On entry, must have lo <= start <= hi, and that [lo, start) is already
        sorted (pass start == lo if you don't know!).
        r&   Nrange)r   r   lohir   _has_valuesZpivotlrpZ	pivot_val)r;   r$   r!   r#   r      s,    

z%make_timsort_impl.<locals>.binarysortc                    s   ||k sJ |d |krdS  | |d  | | rxt |d |D ]*} | | | |d  s@|| df  S q@|| dfS t |d |D ]*} | | | |d  r|| df  S q|| dfS dS )a  
        Return the length of the run beginning at lo, in the slice [lo, hi).
        lo < hi is required on entry.  "A run" is the longest ascending sequence, with

            lo[0] <= lo[1] <= lo[2] <= ...

        or the longest descending sequence, with

            lo[0] > lo[1] > lo[2] > ...

        A tuple (length, descending) is returned, where boolean *descending*
        is set to 0 in the former case, or to 1 in the latter.
        For its intended use in a stable mergesort, the strictness of the defn of
        "descending" is needed so that the caller can safely reverse a descending
        sequence without violating stability (strict > ensures there are no equal
        elements to get out of order).
        r&   )r&   Fr%   TFNr=   )r   r?   r@   kr;   r!   r#   r      s    z$make_timsort_impl.<locals>.count_runc           
         st  ||ksJ ||kr||k s J || }d}d} || | r|| }||k r |||  | r|}|d> d }|dkr|}qFqqF||kr|}||7 }||7 }nf|| d }||k r |||  | rqq|}|d> d }|dkr|}q||kr|}|| ||  }}|d |kr(||k r(||ks,J |d7 }||k rp||| d?  }	 ||	 | rh|	d }n|	}q4|S )a  
        Locate the proper position of key in a sorted vector; if the vector contains
        an element equal to key, return the position immediately to the left of
        the leftmost equal element.  [gallop_right() does the same except returns
        the position to the right of the rightmost equal element (if any).]

        "a" is a sorted vector with stop elements, starting at a[start].
        stop must be > start.

        "hint" is an index at which to begin the search, start <= hint < stop.
        The closer hint is to the final result, the faster this runs.

        The return value is the int k in start..stop such that

            a[k-1] < key <= a[k]

        pretending that a[start-1] is minus infinity and a[stop] is plus infinity.
        IOW, key belongs at index k; or, IOW, the first k elements of a should
        precede key, and the last stop-start-k should follow key.

        See listsort.txt for info on the method.
        r   r&   r!   
keyr9   r   stophintr   ZlastofsZofsZmaxofsmrF   r!   r#   r      sJ    
&

z&make_timsort_impl.<locals>.gallop_leftc           
         st  ||ksJ ||kr||k s J || }d}d} | || r|| d }||k r | |||  r|}|d> d }|dkr|}qJqqJ||kr|}|| ||  }}n`|| }||k r | |||  rqq|}|d> d }|dkr|}q||kr|}||7 }||7 }|d |kr(||k r(||ks,J |d7 }||k rp||| d?  }	 | ||	 rd|	}n|	d }q4|S )a  
        Exactly like gallop_left(), except that if key already exists in a[start:stop],
        finds the position immediately to the right of the rightmost equal value.

        The return value is the int k in start..stop such that

            a[k-1] <= key < a[k]

        The code duplication is massive, but this is enough different given that
        we're sticking to "<" comparisons that it's much harder to follow if
        written as one routine with yet another "left or right?" flag.
        r   r&   r!   rG   rF   r!   r#   r   ;  sJ    &
z'make_timsort_impl.<locals>.gallop_rightc                 S   s6   d}| dksJ | dkr.|| d@ O }| dL } q| | S )a  
        Compute a good value for the minimum run length; natural runs shorter
        than this are boosted artificially via binary insertion.

        If n < 64, return n (it's too small to bother with fancy stuff).
        Else if n is an exact power of 2, return 32.
        Else return an int k, 32 <= k <= 64, such that n/k is close to, but
        strictly less than, an exact power of 2.

        See listsort.txt for more info.
        r   @   r&   r!   )r   rC   r!   r!   r#   r     s    
z/make_timsort_impl.<locals>.merge_compute_minrunc                    sj   |dksJ |dksJ t |D ]}|||  | || < q  ||rft |D ]}|||  ||| < qLdS )z#
        Upwards memcpy().
        r   Nr=   Z	dest_keysZdest_valuesZ
dest_startZsrc_keysZ
src_valuesZ	src_startZnitemsir$   r!   r#   sortslice_copy  s    
z)make_timsort_impl.<locals>.sortslice_copyc                    sj   |dksJ |dksJ t |D ]}|||  | || < q  ||rft |D ]}|||  ||| < qLdS )z%
        Downwards memcpy().
        r   Nr=   rM   rO   r!   r#   sortslice_copy_down  s    
z.make_timsort_impl.<locals>.sortslice_copy_downr&   c                    sL  |dkr|dkr||ksJ ||| ks,J | |} | j | jd|||| | j }| j}|}	|}
|}d}||}| j}|dkr|dkrd}d}|	| || r|	| ||< |r|
| ||< |d7 }|d7 }|d8 }|dkrqd|d7 }d}||krbqdq|| ||< |r$|| ||< |d7 }|d7 }|d8 }|dkrJqd|d7 }d}||krqdq rz|dkrz|dkrz|d7 }|tks|tkr||dk8 }|	| |||| |}||8 }|}|dkr||||||| ||7 }||7 }||8 }|dkrq|	| ||< |r&|
| ||< |d7 }|d7 }|d8 }|dkrLq|| |	||| |}||8 }|}|dkr||||	|
|| ||7 }||7 }||8 }|dkrq|| ||< |r|| ||< |d7 }|d7 }|d8 }|dkrqq|d7 }qz|dkr&||||||| n|dks4J ||ksBJ | |S )a@  
        Merge the na elements starting at ssa with the nb elements starting at
        ssb = ssa + na in a stable way, in-place.  na and nb must be > 0,
        and should have na <= nb. See listsort.txt for more info.

        An updated MergeState is returned (with possibly a different min_gallop
        or larger temp arrays).

        NOTE: compared to CPython's timsort, the requirement that
            "Must also have that keys[ssa + na - 1] belongs at the end of the merge"

        is removed. This makes the code a bit simpler and easier to reason about.
        r   r&   r   r   r   r,   r5   r   r   ssanassbnbZa_keysZa_valuesZb_keysZb_valuesdestrA   r   ZacountZbcountrE   )	DO_GALLOPr;   r   r   r$   r8   r7   rP   r!   r#   r     s    











z#make_timsort_impl.<locals>.merge_loc                    s  |dkr|dkr||ksJ ||| ks,J | |} | j | jd|||| |}|}| j }	| j}
|| d }|d }|| d }|	|
}| j}|dkr8|dkr8d}d}|	| || r || ||< |r|| ||< |d8 }|d8 }|d8 }|dkrq~|d7 }d}||kr|q~q|	| ||< |r>|
| ||< |d8 }|d8 }|d8 }|dkrdq~|d7 }d}||krq~q r|dkr|dkr|d7 }|tks|tkr.||dk8 }|	| ||| d |d |}|d | }|}|dkr.||||||| ||8 }||8 }||8 }|dkr.q.|	| ||< |rL|
| ||< |d8 }|d8 }|d8 }|dkrrq.|| |	|| d |d |}|d | }|}|dkr||||	|
|| ||8 }||8 }||8 }|dkrq.|| ||< |r|| ||< |d8 }|d8 }|d8 }|dkrq.q|d7 }q|dkrh|||| d |	|
|| d | n|dksvJ ||ksJ | |S )aA  
        Merge the na elements starting at ssa with the nb elements starting at
        ssb = ssa + na in a stable way, in-place.  na and nb must be > 0,
        and should have na >= nb.  See listsort.txt for more info.

        An updated MergeState is returned (with possibly a different min_gallop
        or larger temp arrays).

        NOTE: compared to CPython's timsort, the requirement that
            "Must also have that keys[ssa + na - 1] belongs at the end of the merge"

        is removed. This makes the code a bit simpler and easier to reason about.
        r   r&   rR   rS   )	rY   r;   r   r   r$   r8   r7   rP   rQ   r!   r#   r   Y  s    




 


 




z#make_timsort_impl.<locals>.merge_hic           
         sX  | j }|dksJ |dksJ ||d ks:||d ks:J | j| \}}| j|d  \}}|dkrj|dksnJ || |ks~J t||| | j|< ||d kr| j|d  | j|d < | } || |||| |}	||	| 8 }|	}|dkr| S  ||| d  |||| || d }	|	| }||kr@| ||||||S | ||||||S dS )zl
        Merge the two runs at stack indices i and i+1.

        An updated MergeState is returned.
        r%   r      r&   N)r   r   r   )
r5   r   r   rN   r   rT   rU   rV   rW   rE   )r   r   r   r   r   r!   r#   r     s,    (
z#make_timsort_impl.<locals>.merge_atc                    s   | j dkr| j}| j d }|dkrH||d  j|| j||d  j ksv|dkr||d  j||d  j|| j kr||d  j||d  jk r|d8 } | |||} q || j||d  jk rֈ | |||} q qq | S )a(  
        Examine the stack of runs waiting to be merged, merging adjacent runs
        until the stack invariants are re-established:

        1. len[-3] > len[-2] + len[-1]
        2. len[-2] > len[-1]

        An updated MergeState is returned.

        See listsort.txt for more info.
        r&   r%   r   r   r   r   r5   r   r   r   r   r   r!   r#   r   '  s    

.$z)make_timsort_impl.<locals>.merge_collapsec                    sZ   | j dkrV| j}| j d }|dkrF||d  j||d  jk rF|d8 } | |||} q | S )z
        Regardless of invariants, merge all runs on the stack until only one
        remains.  This is used at the end of the mergesort.

        An updated MergeState is returned.
        r&   r%   r   r[   r\   r]   r!   r#   r   C  s    

z/make_timsort_impl.<locals>.merge_force_collapsec                    s   |}|d }||k r@| | | |  | |< | |< |d7 }|d8 }q | |r|}|d }||k r|| ||  ||< ||< |d7 }|d8 }qVdS )z,
        Reverse a slice, in-place.
        r&   Nr!   )r   r   r   rI   rN   jrO   r!   r#   reverse_sliceV  s    

z(make_timsort_impl.<locals>.reverse_slicec           	         s   t |}|dk rdS |}}|dkr|||| \}}|rR|||||  ||k rt||} ||||| ||  |}| t||} | ||} ||7 }||8 }q | ||} | jdksJ | jd dt |fksJ dS )z2
        Run timsort with the mergestate.
        r%   Nr   r&   )r)   r(   r   r   r   )	r5   r   r   Z
nremainingZminrunr?   r   descforce)r   r   r
   r   r   r   r_   r3   r!   r#   run_timsort_with_mergestatej  s(    

z6make_timsort_impl.<locals>.run_timsort_with_mergestatec                    s   | } | | | dS )z2
        Run timsort over the given keys.
        Nr!   r"   )r	   rb   r!   r#   r     s    z&make_timsort_impl.<locals>.run_timsortc                    s    | || | dS )z=
        Run timsort over the given keys and values.
        Nr!   r"   )r4   rb   r!   r#   r     s    
z2make_timsort_impl.<locals>.run_timsort_with_values)r   r1   r   )wrapr2   r   r   r!   )rY   r;   r   r   r   r   r$   r1   r2   r8   r
   r   r   r   r   r7   r   r	   r4   r   r   r_   rb   rP   rQ   r3   r#   make_timsort_impl9   s|    



	

1$UK
  /$rd   c                  G   s   t dd g| R  S )Nc                 S   s   | S r    r!   fr!   r!   r#   <lambda>      z!make_py_timsort.<locals>.<lambda>)rd   argsr!   r!   r#   make_py_timsort  s    rk   c                     s$   ddl m  t fddg| R  S )Nr   jitc                    s    dd| S )NT)Znopythonr!   re   rl   r!   r#   rg     rh   z"make_jit_timsort.<locals>.<lambda>)Znumbarm   rd   ri   r!   rl   r#   make_jit_timsort  s    rn   )__doc__collectionsZ
numba.corer   
namedtupler   r+   r,   r*   r   r   rd   rk   rn   r!   r!   r!   r#   <module>   s,   	      v