
    xKg߂                         d Z ddlZddlmZ  ej                  dd      ZdZdZdZ ej                  d	d
      Z	 ej                  dd      Z
d Zd Zd Zy)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                   	
  |       t         j                   d      | d        
| fd       | fd       | d        | d        | 
fd       | fd       | d	        | 
fd
       | fd       | fd       | fd       	| d        | 
fd       | 
fd       d| 	
fd       | 	
f	d       | 	fd       | fd       | fd       | 
fd       | fd       | fd       }| fd       }t        | 	||      S )Nr   c                 
    || uS N )r   r   s     V/home/alanp/www/video.onchill/myenv/lib/python3.12/site-packages/numba/misc/timsort.py
has_valuesz%make_timsort_impl.<locals>.has_values?   s    T!!    c                     t        t        |       dz  dz   t              } | |      }|}t              gt        z  }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zeros        r%   r
   z%make_timsort_impl.<locals>.merge_initC   s]    
 D	Q*,@A	"43	D$'(+<<$z*I{GTRRr'   c                     t        t        |       dz  dz   t              } | |      } ||      }t              gt        z  }t         t              |||      S )z;
        Initialize a MergeState for a keyed sort.
        r)   r*   r+   )	r   r   r1   r2   r3   r   r4   r5   r6   s	         r%   merge_init_with_valuesz1make_timsort_impl.<locals>.merge_init_with_valuesN   sd    
 D	Q*,@A	"43	$VY7D$'(+<<$z*I{GTRRr'   c                     | j                   }|t        k  sJ || j                  |<   t        | j                  | j
                  | j                  | j                  |dz         S )z2
        Append a run on the merge stack.
        r*   )r   r/   r   r   r   r   r   )msrunr   s      r%   r   z'make_timsort_impl.<locals>.merge_appendY   sP    
 DD$$$$

1"--"))RZZQOOr'   c                     t        | j                  | j                  | j                  | j                  | j
                  dz
        S )z7
        Pop the top run from the merge stack.
        r*   )r   r   r   r   r   r   )r:   s    r%   r   z$make_timsort_impl.<locals>.merge_popc   s0    
 "--"))RZZPQRRr'   c                 B   t        | j                        }||k  r| S ||k  r|dz  }||k  r | j                  |      } | j                  | j                        r | 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   )r:   needallocedr2   r3   r&   r5   s        r%   merge_getmemz'make_timsort_impl.<locals>.merge_getmemj   s    
 bgg,7?InlG n #277G4	bggryy)(G<K#K"--KRTTRRr'   c                 ~    t         |      | j                  | j                  | j                  | j                        S )z5
        Modify the MergeState's min_gallop.
        )r   r   r   r   r   )r:   
new_gallopr4   s     r%   merge_adjust_gallopz.make_timsort_impl.<locals>.merge_adjust_gallop~   s-    
 $z*BGGRYY

BDDQQr'   c                     | |k  S )z
        Trivial comparison function between two keys.  This is factored out to
        make it clear where comparisons occur.
        r$   )abs     r%   LTzmake_timsort_impl.<locals>.LT   s     1ur'   c                 b   ||k  r||k  sJ  | |      }||k(  r|dz  }||k  r| |   }|}|}||k  r%|||z
  dz	  z   }	 || |	         r|	}n|	dz   }||k  r%t        ||d      D ]  }	| |	dz
     | |	<    || |<   |r'||   }
t        ||d      D ]  }	||	dz
     ||	<    |
||<   |dz  }||k  ryy)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_valuespivotlrp	pivot_valrG   r&   s              r%   r   z%make_timsort_impl.<locals>.binarysort   s    U{u{** v.;QJEbjKE AA
 a%!a%A&eT!W%A!A a% 5!R(q1u+Q )DG"5M	ua,A &q1uF1I -%q	QJEA bjr'   c                     ||k  sJ |dz   |k(  ry | |dz      | |         r6t        |dz   |      D ]  } | |   | |dz
           r||z
  dfc S  ||z
  dfS t        |dz   |      D ]  } | |   | |dz
           s||z
  dfc S  ||z
  df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)   TFrJ   )r   rL   rM   krG   s       r%   r   z$make_timsort_impl.<locals>.count_run   s    & Bww6R<d26lDH%262&$q'4A;/r64<' ' 7D=  262&d1gtAE{+r65=( ' 7E>!r'   c                    ||kD  sJ ||k\  r||k  sJ ||z
  }d}d} 
||   |       rD||z
  }||k  r( 
|||z      |       r|}|dz  dz   }|dk  r|}nn||k  r(||kD  r|}||z  }||z  }nE||z
  dz   }||k  r' 
|||z
     |       rn|}|dz  dz   }|dk  r|}||k  r'||kD  r|}||z
  ||z
  }}|dz
  |k  r
||k  r||k  sJ |dz  }||k  r%|||z
  dz	  z   }	 
||	   |       r|	dz   }n|	}||k  r%|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$   keyrE   r   stophintr   lastofsofsmaxofsmrG   s             r%   r   z&make_timsort_impl.<locals>.gallop_left   s   0 e||u},,5L ags D[F,as
mS)!G!8q.Cax$  , V|tOG4KC E\A%F,as
mS) "G!8q.Cax$ , V|#:tg~SGqyG###+EE 	1mC'Ma/0A!A$}a%  m 
r'   c                    ||kD  sJ ||k\  r||k  sJ ||z
  }d}d} 
| ||         rG||z
  dz   }||k  r( 
| |||z
           r|}|dz  dz   }|dk  r|}nn||k  r(||kD  r|}||z
  ||z
  }}nB||z
  }||k  r' 
| |||z            rn|}|dz  dz   }|dk  r|}||k  r'||kD  r|}||z  }||z  }|dz
  |k  r
||k  r||k  sJ |dz  }||k  r%|||z
  dz	  z   }	 
| ||	         r|	}n|	dz   }||k  r%|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$   rW   s             r%   r	   z'make_timsort_impl.<locals>.gallop_right;  s    e||u},,5L c1T7 E\A%F,c1TCZ=)!G!8q.Cax$  , V|#:tg~SG D[F,c1TCZ=) "G!8q.Cax$ , V|tOG4KCqyG###+EE 	1mC'Ma/0A#qt} a% m 
r'   c                 N    d}| dk\  sJ | dk\  r|| dz  z  }| dz  } | dk\  r| |z   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   rQ   s     r%   r   z/make_timsort_impl.<locals>.merge_compute_minrun  sE     Avv2gQJA!GA 2g 1ur'   c                     |dk\  sJ |dk\  sJ t        |      D ]  }|||z      | ||z   <     ||      rt        |      D ]  }|||z      |||z   <    yy)z#
        Upwards memcpy().
        r   NrJ   		dest_keysdest_values
dest_startsrc_keys
src_values	src_startnitemsir&   s	           r%   sortslice_copyz)make_timsort_impl.<locals>.sortslice_copy  v     A~~QvA(0Q(?Ij1n% h
+6].8Q.GJN+ # ,r'   c                     |dk\  sJ |dk\  sJ t        |      D ]  }|||z
     | ||z
  <     ||      rt        |      D ]  }|||z
     |||z
  <    yy)z%
        Downwards memcpy().
        r   NrJ   rc   s	           r%   sortslice_copy_downz.make_timsort_impl.<locals>.sortslice_copy_down  rm   r'   r*   c           	         |dkD  r
|dkD  r||k  sJ |||z   k(  sJ  | |      }  | j                   | j                  d||||       | j                   }| j                  }|}	|}
|}d} ||      }| j                  }|dkD  r|dkD  rd}d}	  |	|   ||         r4|	|   ||<   |r|
|   ||<   |dz  }|dz  }|dz  }|dk(  rnB|dz  }d}||k\  r5n5||   ||<   |r||   ||<   |dz  }|dz  }|dz  }|dk(  rn|dz  }d}||k\  rnxr|dkD  r|dkD  r|dz  }|t        k\  s	|t        k\  r||dkD  z  } |	|   ||||z   |      }||z  }|}|dkD  r# |||||||       ||z  }||z  }||z  }|dk(  rn|	|   ||<   |r|
|   ||<   |dz  }|dz  }|dz  }|dk(  rn| ||   |	|||z   |      }||z  }|}|dkD  r# ||||	|
||       ||z  }||z  }||z  }|dk(  rn;||   ||<   |r||   ||<   |dz  }|dz  }|dz  }|dk(  rn|t        k\  r|t        k\  r|dz  }|dkD  r|dkD  r|dk(  r |||||||       n|dk(  sJ ||k(  sJ  | |      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   r0   )r:   r   r   ssanassbnba_keysa_valuesb_keysb_valuesdestrN   r   acountbcountrU   	DO_GALLOPrG   r   r	   r&   rC   r@   rl   s                    r%   r   z#make_timsort_impl.<locals>.merge_lo  s    Av"q&R2X--cBh"b!rww		1VS	 99 2]]
 1fa FFfSk6#;/!'DJ"'/}tAID1HC!GBQwaKFF+!'DJ"'/}tAID1HC!GBQwaKFF+9 D R!VQa

*f
.B *q.0J %VC[&#sRxMAHAF1u&tVT'-x'(* 	qa7!!'DJ"'/}tAID1HC!GBQw $F3KcBhLAHAF1u 'tVT'-x'(* 	qa7!!'DJ"'/}tAID1HC!GBQww 
*f
.B| a
S 1faX 74!8S 7N73;; #2z22r'   c           	        	 |dkD  r
|dkD  r||k\  sJ |||z   k(  sJ  | |      }  | j                   | j                  d||||       |}|}| j                   }	| j                  }
||z   dz
  }|dz
  }||z   dz
  } |	|
      }| j                  }|dkD  r|dkD  rd}d}	  |	|   ||         r4||   ||<   |r||   ||<   |dz  }|dz  }|dz  }|dk(  rnB|dz  }d}||k\  r5n5|	|   ||<   |r|
|   ||<   |dz  }|dz  }|dz  }|dk(  rn|dz  }d}||k\  rnxr&|dkD  r |dkD  r|dz  }|t        k\  s	|t        k\  r||dkD  z  } |	|   |||z
  dz   |dz   |      }|dz   |z
  }|}|dkD  r# |||||||       ||z  }||z  }||z  }|dk(  rn|	|   ||<   |r|
|   ||<   |dz  }|dz  }|dz  }|dk(  rn ||   |	||z
  dz   |dz   |      }|dz   |z
  }|}|dkD  r# ||||	|
||       ||z  }||z  }||z  }|dk(  rn;||   ||<   |r||   ||<   |dz  }|dz  }|dz  }|dk(  rn|t        k\  r|t        k\  r|dz  }|dkD  r|dkD  r|dk(  r ||||z
  dz   |	|
||z
  dz   |       n|dk(  sJ ||k(  sJ  | |      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*   rq   )r:   r   r   rr   rs   rt   ru   rv   rw   rx   ry   rz   rN   r   r{   r|   rU   r}   rG   r   r	   r&   rC   r@   rl   ro   s                    r%   r   z#make_timsort_impl.<locals>.merge_hiY  s    Av"q&R2X--cBh"b!rww		1VS	 99 Rx!|1fBhl 2]]
1fa FFfSk6#;/!'DJ"'/}tAID1HC!GBQwaKFF+!'DJ"'/}tAID1HC!GBQwaKFF+; F R!VQa

*f
.B *q.0J %VC[&#(Q,aQTUAa!AF1u ,D&$,2Hc,-/ 	qa7!!'DJ"'/}tAID1HC!GBQw $F3KrAsQwPSTAa!AF1u+D&$,2Hc,-/ 	qa7!!'DJ"'/}tAID1HC!GBQww 
*f
.B| a
U 1faZ 74Q!8S2X\ 7N73;; #2z22r'   c           	      @   | j                   }|dk\  sJ |dk\  sJ ||dz
  k(  s
||dz
  k(  sJ | j                  |   \  }}| j                  |dz      \  }}|dkD  r|dkD  sJ ||z   |k(  sJ t        |||z         | j                  |<   ||dz
  k(  r"| j                  |dz      | j                  |dz   <    |       }  ||   ||||z   |      }	||	|z
  z  }|	}|dk(  r| S  
|||z   dz
     ||||z   ||z   dz
        }	|	|z
  }||k  r | ||||||      S  | ||||||      S )zl
        Merge the two runs at stack indices i and i+1.

        An updated MergeState is returned.
        r)   r      r*   )r   r   r   )r:   r   r   rk   r   rr   rs   rt   ru   rU   r   r	   r   r   r   s             r%   r   z#make_timsort_impl.<locals>.merge_at  s}    DDAvvAvvAEzQ!a%Z''**Q-R**QU#RAv"q&  Rx3
 !b2g.

1A: "

1q5 1BJJq1ur] cD#sRx=
a#g7I S2X\*D#sRxrANW 8Bfc2sB??Bfc2sB??r'   c                 6   | j                   dkD  r| j                  }| j                   dz
  }|dkD  r5||dz
     j                  ||   j                  ||dz      j                  z   k  s:|dkD  rk||dz
     j                  ||dz
     j                  ||   j                  z   k  r6||dz
     j                  ||dz      j                  k  r|dz  } | |||      } n1||   j                  ||dz      j                  k  r | |||      } n	 | S | j                   dkD  r| 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    r:   r   r   r   r   r   s        r%   r   z)make_timsort_impl.<locals>.merge_collapse'  s    ddQhjjGqAQ71Q3<,,
'!A#,BSBS0SSQ71Q3<,,!0A0AGAJOO0SS1q5>&&Q)<)<<FAb$271q5>#6#66b$2	 ddQh 	r'   c                     | j                   dkD  re| j                  }| j                   dz
  }|dkD  r*||dz
     j                  ||dz      j                  k  r|dz  } | |||      } | j                   dkD  re| 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   s        r%   r   z/make_timsort_impl.<locals>.merge_force_collapseC  s~     ddQhjjGqA1u1q5>&&Q)<)<<FA"dFA.B ddQh 	r'   c                     |}|dz
  }||k  r!| |   | |   c| |<   | |<   |dz  }|dz  }||k  r! | |      r/|}|dz
  }||k  r"||   ||   c||<   ||<   |dz  }|dz  }||k  r!yyy)z,
        Reverse a slice, in-place.
        r*   Nr$   )r   r   r   rY   rk   jr&   s         r%   reverse_slicez(make_timsort_impl.<locals>.reverse_sliceV  s    
 1H!e#AwQDGT!WFAFA !e dF#AqAa%'-ay&)$q	6!9QQ a% $r'   c                    t        |      }|dk  ry |      }}|dkD  rr 
||||z         \  }}|r |||||z          ||k  r t        ||      } 	|||||z   ||z          |} | t        ||            }  | ||      } ||z  }||z  }|dkD  rr | ||      } | j                  dk(  sJ | j                  d   dt        |      fk(  sJ y)z2
        Run timsort with the mergestate.
        r)   Nr   r*   )r-   r,   r   r   r   )r:   r   r   
nremainingminrunrL   r   descforcer   r   r   r   r   r   r   r6   s            r%   run_timsort_with_mergestatez6make_timsort_impl.<locals>.run_timsort_with_mergestatej  s   
 Y
> &j11nb"z/:GAtdFBQ76zFJ/4R%Za@b(2q/2BD&1B!GB!OJ 1n$ ""dF3ttqyyzz!}CI...r'   c                 *    | }  |       | |       y)z2
        Run timsort over the given keys.
        Nr$   )r   r   r
   r   s     r%   r   z&make_timsort_impl.<locals>.run_timsort  s    
 #Jt$4dFCr'   c                 (      | |      | |       y)z=
        Run timsort over the given keys and values.
        Nr$   )r   r   r8   r   s     r%   r   z2make_timsort_impl.<locals>.run_timsort_with_values  s    
 	$$:4$H$(&	2r'   )r   r4   r   )wrapr5   r   r   r}   rG   r   r   r   r	   r&   r4   rC   r   r   r   r   r   r@   r   r
   r8   r   r   r   r   rl   ro   r6   s    `  @@@@@@@@@@@@@@@@@@@@@@@@@r%   make_timsort_implr   9   sp   .)N::D7D	" 
" 
S 
S 
S 
S 
P 
P 
S 
S 
S 
S& 
R 
R 
 
 
. 
.b 
!" 
!"H 
R 
Rj 
H 
HV 
 
( 
H 
H 
H 
H  I	W3 W3 
W3t 
Z3 Z3 
Z3z 
,@ 
,@^ 
 
6 
 
$ 
 
& 
!/ !/ 
!/H 
D 
D 
2 
2 !:{LL)h(n,. .r'   c                      t        d g|  S )Nc                     | S r#   r$   )fs    r%   <lambda>z!make_py_timsort.<locals>.<lambda>  s    r'   )r   )argss    r%   make_py_timsortr     s    k2T22r'   c                  .    ddl m t        fdg|  S )Nr   )jitc                 "      d      |       S )NT)nopythonr$   )r   r   s    r%   r   z"make_jit_timsort.<locals>.<lambda>  s    (:T(:1(=r'   )numbar   r   )r   r   s    @r%   make_jit_timsortr     s    = %#% %r'   )__doc__collections
numba.corer   
namedtupler   r/   r0   r.   r   r   r   r   r   r$   r'   r%   <module>r      s      /..	 *   
   $[##BD
 ";!!*.?@m.`3%r'   