ó
\K]c           @` sê   d  Z  d d l m Z m Z m Z d d l Z d d l m Z e j d d d d d	 d
 d d d d d d d d d d d f ƒ Z	 d Z
 d Z d Z e j d d d d d d f ƒ Z e j d d  d! f ƒ Z d" „  Z d# „  Z d$ „  Z d S(%   sˆ   
Timsort implementation.  Mostly adapted from CPython's listobject.c.

For more information, see listsort.txt in CPython's source tree.
i    (   t   print_functiont   absolute_importt   divisionN(   t   typest   TimsortImplementationt   compilet	   count_runt
   binarysortt   gallop_leftt   gallop_rightt
   merge_initt   merge_appendt	   merge_popt   merge_compute_minrunt   merge_lot   merge_hit   merge_att   merge_force_collapset   merge_collapset   run_timsortt   run_timsort_with_valuesiU   i   i   t
   MergeStatet
   min_gallopt   keyst   valuest   pendingt   nt   MergeRunt   startt   sizec         ` sž  |  ˆ ƒ ‰ 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(   Ni    c         S` s
   | |  k	 S(   N(    (   R   R   (    (    s2   lib/python2.7/site-packages/numba/tests/timsort.pyt
   has_values@   s    c         ` sd   t  t |  ƒ d d t ƒ } ˆ |  | ƒ } | } t ˆ ˆ ƒ g t } t ˆ  t ƒ | | | ˆ ƒ S(   s?   
        Initialize a MergeState for a non-keyed sort.
        i   i   (   t   mint   lent   MERGESTATE_TEMP_SIZER   t   MAX_MERGE_PENDINGR   t
   MIN_GALLOP(   R   t	   temp_sizet	   temp_keyst   temp_valuesR   (   t   intpt   make_temp_areat   zero(    s2   lib/python2.7/site-packages/numba/tests/timsort.pyR
   D   s
    c         ` sm   t  t |  ƒ d d t ƒ } ˆ |  | ƒ } ˆ | | ƒ } t ˆ ˆ ƒ g t } t ˆ  t ƒ | | | ˆ ƒ S(   s;   
        Initialize a MergeState for a keyed sort.
        i   i   (   R   R    R!   R   R"   R   R#   (   R   R   R$   R%   R&   R   (   R'   R(   R)   (    s2   lib/python2.7/site-packages/numba/tests/timsort.pyt   merge_init_with_valuesO   s
    c         S` sN   |  j  } | t k  s t ‚ | |  j | <t |  j |  j |  j |  j | d ƒ S(   s2   
        Append a run on the merge stack.
        i   (   R   R"   t   AssertionErrorR   R   R   R   R   (   t   mst   runR   (    (    s2   lib/python2.7/site-packages/numba/tests/timsort.pyR   Z   s    	c         S` s)   t  |  j |  j |  j |  j |  j d ƒ S(   s7   
        Pop the top run from the merge stack.
        i   (   R   R   R   R   R   R   (   R,   (    (    s2   lib/python2.7/site-packages/numba/tests/timsort.pyR   d   s    c         ` s   t  |  j ƒ } | | k r |  Sx | | k  r; | d >} q" Wˆ |  j | ƒ } ˆ  |  j |  j ƒ rx ˆ |  j | ƒ } n | } t |  j | | |  j |  j ƒ S(   sJ   
        Ensure enough temp memory for 'need' items is available.
        i   (   R    R   R   R   R   R   R   (   R,   t   needt   allocedR%   R&   (   R   R(   (    s2   lib/python2.7/site-packages/numba/tests/timsort.pyt   merge_getmemk   s    c         ` s(   t  ˆ  | ƒ |  j |  j |  j |  j ƒ S(   s5   
        Modify the MergeState's min_gallop.
        (   R   R   R   R   R   (   R,   t
   new_gallop(   R'   (    s2   lib/python2.7/site-packages/numba/tests/timsort.pyt   merge_adjust_gallop   s    c         S` s
   |  | k  S(   s‡   
        Trivial comparison function between two keys.  This is factored out to
        make it clear where comparisons occur.
        (    (   t   at   b(    (    s2   lib/python2.7/site-packages/numba/tests/timsort.pyt   LT‡   s    c         ` sM  | | k r | | k s t  ‚ ˆ |  | ƒ } | | k rF | d 7} n  x | | k  rH|  | } | } | } xH | | k  rµ | | | d ?}	 ˆ  | |  |	 ƒ r¨ |	 } qn |	 d } qn Wx, t | | d ƒ D] }	 |  |	 d |  |	 <qÉ W| |  | <| r;| | }
 x, t | | d ƒ D] }	 | |	 d | |	 <qW|
 | | <n  | d 7} qI Wd S(   s¦  
        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!).
        i   iÿÿÿÿN(   R+   t   range(   R   R   t   lot   hiR   t   _has_valuest   pivott   lt   rt   pt	   pivot_val(   R5   R   (    s2   lib/python2.7/site-packages/numba/tests/timsort.pyR      s,    
	

c         ` sõ   | | k  s t  ‚ | d | k r, d t f Sˆ  |  | d |  | ƒ rœ xD t | d | ƒ D]/ } ˆ  |  | |  | d ƒ s[ | | t f Sq[ W| | t f SxD t | d | ƒ D]/ } ˆ  |  | |  | d ƒ r° | | t f Sq° W| | t f Sd S(   sÞ  
        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).
        i   i   N(   R+   t   FalseR6   t   True(   R   R7   R8   t   k(   R5   (    s2   lib/python2.7/site-packages/numba/tests/timsort.pyR   Á   s    
c   
      ` sü  | | k s t  ‚ | | k r* | | k  s0 t  ‚ | | } d } d } ˆ  | | |  ƒ ræ | | } xT | | k  r¹ ˆ  | | | |  ƒ rµ | } | d >d } | d k r¶ | } q¶ qf Pqf W| | k rÏ | } n  | | 7} | | 7} n | | d } xT | | k  rJˆ  | | | |  ƒ rPq÷ | } | d >d } | d k r÷ | } q÷ q÷ W| | k r`| } n  | | | | } } | d | k r| | k  r| | k s£t  ‚ | d 7} xH | | k  r÷| | | d ?}	 ˆ  | |	 |  ƒ rî|	 d } q°|	 } q°W| S(   sÃ  
        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.
        i    i   (   R+   (
   t   keyR3   R   t   stopt   hintR   t   lastofst   ofst   maxofst   m(   R5   (    s2   lib/python2.7/site-packages/numba/tests/timsort.pyR   æ   sJ    

	
	.

c   
      ` sü  | | k s t  ‚ | | k r* | | k  s0 t  ‚ | | } d } d } ˆ  |  | | ƒ rë | | d } xT | | k  r½ ˆ  |  | | | ƒ r¹ | } | d >d } | d k rº | } qº qj Pqj W| | k rÓ | } n  | | | | } } nŠ | | } xT | | k  rKˆ  |  | | | ƒ rPqø | } | d >d } | d k rø | } qø qø W| | k ra| } n  | | 7} | | 7} | d | k r| | k  r| | k s£t  ‚ | d 7} xH | | k  r÷| | | d ?}	 ˆ  |  | |	 ƒ rê|	 } q°|	 d } q°W| S(   sû  
        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.
        i    i   (   R+   (
   RB   R3   R   RC   RD   R   RE   RF   RG   RH   (   R5   (    s2   lib/python2.7/site-packages/numba/tests/timsort.pyR	   <  sJ    
	
	

.
	c         S` sK   d } |  d k s t  ‚ x( |  d k rB | |  d @O} |  d L}  q W|  | S(   s½  
        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.
        i    i@   i   (   R+   (   R   R<   (    (    s2   lib/python2.7/site-packages/numba/tests/timsort.pyR   ˆ  s    c         ` s”   | d k s t  ‚ | d k s$ t  ‚ x* t | ƒ D] } | | | |  | | <q1 Wˆ  | | ƒ r x- t | ƒ D] } | | | | | | <qm Wn  d S(   s#   
        Upwards memcpy().
        i    N(   R+   R6   (   t	   dest_keyst   dest_valuest
   dest_startt   src_keyst
   src_valuest	   src_startt   nitemst   i(   R   (    s2   lib/python2.7/site-packages/numba/tests/timsort.pyt   sortslice_copy  s    c         ` s”   | d k s t  ‚ | d k s$ t  ‚ x* t | ƒ D] } | | | |  | | <q1 Wˆ  | | ƒ r x- t | ƒ D] } | | | | | | <qm Wn  d S(   s%   
        Downwards memcpy().
        i    N(   R+   R6   (   RI   RJ   RK   RL   RM   RN   RO   RP   (   R   (    s2   lib/python2.7/site-packages/numba/tests/timsort.pyt   sortslice_copy_down¬  s    i   c         ` sc  | d k r$ | d k r$ | | k s* t  ‚ | | | k s@ t  ‚ ˆ |  | ƒ }  ˆ |  j |  j d | | | | ƒ |  j } |  j } | }	 | }
 | } d } ˆ | | ƒ } |  j } xQ| d k r| d k rd } d } x
t ræˆ |	 | | | ƒ rp|	 | | | <| r|
 | | | <n  | d 7} | d 7} | d 8} | d k rMPn  | d 7} d } | | k rãPqãqÝ | | | | <| r•| | | | <n  | d 7} | d 7} | d 8} | d k rÃPn  | d 7} d } | | k rÝ PqÝ qÝ Wˆ  r¶ | d k r¶ | d k r¶ | d 7} xä| t k s*| t k rõ| | d k 8} ˆ |	 | | | | | | ƒ } | | 8} | } | d k rÃˆ | | | | | | | ƒ | | 7} | | 7} | | 8} | d k rÃPqÃn  |	 | | | <| rè|
 | | | <n  | d 7} | d 7} | d 8} | d k rPn  ˆ | | |	 | | | | ƒ } | | 8} | } | d k rŸˆ | | | |	 |
 | | ƒ | | 7} | | 7} | | 8} | d k rŸPqŸn  | | | | <| rÄ| | | | <n  | d 7} | d 7} | d 8} | d k rPqqW| d 7} q¶ q¶ W| d k r2ˆ | | | | | | | ƒ n$ | d k sDt  ‚ | | k sVt  ‚ ˆ |  | ƒ S(   s@  
        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.
        i    i   (   R+   R   R   R   R@   R#   (   R,   R   R   t   ssat   nat   ssbt   nbt   a_keyst   a_valuest   b_keyst   b_valuest   destR9   R   t   acountt   bcountRA   (   t	   DO_GALLOPR5   R   R	   R   R2   R0   RQ   (    s2   lib/python2.7/site-packages/numba/tests/timsort.pyR   ¿  s¾    *					








 
	





 
	





	
c         ` s¥  | d k r$ | d k r$ | | k s* t  ‚ | | | k s@ t  ‚ ˆ |  | ƒ }  ˆ |  j |  j d | | | | ƒ | } | } |  j }	 |  j }
 | | d } | d } | | d } ˆ |	 |
 ƒ } |  j } xi| d k r8| d k r8d } d } x
t r ˆ |	 | | | ƒ rŠ| | | | <| r9| | | | <n  | d 8} | d 8} | d 8} | d k rgPn  | d 7} d } | | k rýPqýq÷ |	 | | | <| r¯|
 | | | <n  | d 8} | d 8} | d 8} | d k rÝPn  | d 7} d } | | k r÷ Pq÷ q÷ Wˆ  rÐ | d k rÐ | d k rÐ | d 7} xü| t k sD| t k r'| | d k 8} ˆ |	 | | | | d | d | ƒ } | d | } | } | d k réˆ | | | | | | | ƒ | | 8} | | 8} | | 8} | d k réPqén  |	 | | | <| r|
 | | | <n  | d 8} | d 8} | d 8} | d k r<Pn  ˆ | | |	 | | d | d | ƒ } | d | } | } | d k rÑˆ | | | |	 |
 | | ƒ | | 8} | | 8} | | 8} | d k rÑPqÑn  | | | | <| rö| | | | <n  | d 8} | d 8} | d 8} | d k r,Pq,q,W| d 7} qÐ qÐ W| d k rtˆ | | | | d |	 |
 | | d | ƒ n$ | d k s†t  ‚ | | k s˜t  ‚ ˆ |  | ƒ S(   sA  
        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.
        i    i   (   R+   R   R   R   R@   R#   (   R,   R   R   RS   RT   RU   RV   RW   RX   RY   RZ   R[   R9   R   R\   R]   RA   (	   R^   R5   R   R	   R   R2   R0   RQ   RR   (    s2   lib/python2.7/site-packages/numba/tests/timsort.pyR   Z  sÀ    *			
		








(	





(	






c   
      ` sÌ  |  j  } | d k s t ‚ | d k s- t ‚ | | d k sS | | d k sS t ‚ |  j | \ } } |  j | d \ } } | d k r• | d k s› t ‚ | | | k s± t ‚ t | | | ƒ |  j | <| | d k rú |  j | d |  j | d <n  ˆ |  ƒ }  ˆ | | | | | | | ƒ }	 | |	 | 8} |	 } | d k rJ|  Sˆ  | | | d | | | | | | d ƒ }	 |	 | } | | k r¬ˆ |  | | | | | | ƒ Sˆ |  | | | | | | ƒ Sd S(   sl   
        Merge the two runs at stack indices i and i+1.

        An updated MergeState is returned.
        i   i    i   i   N(   R   R+   R   R   (
   R,   R   R   RP   R   RS   RT   RU   RV   RA   (   R   R	   R   R   R   (    s2   lib/python2.7/site-packages/numba/tests/timsort.pyR   ø  s,    	& 0
c         ` s   x|  j  d k r|  j } |  j  d } | d k ra | | d j | | j | | d j k sš | d k rá | | d j | | d j | | j k rá | | d j | | d j k  rÉ | d 8} n  ˆ  |  | | | ƒ }  q | | j | | d j k  rˆ  |  | | | ƒ }  q Pq W|  S(   s(  
        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.
        i   i   i    (   R   R   R   (   R,   R   R   R   R   (   R   (    s2   lib/python2.7/site-packages/numba/tests/timsort.pyR   (  s    	99"c         ` sƒ   x| |  j  d k r~ |  j } |  j  d } | d k rf | | d j | | d j k  rf | d 8} qf n  ˆ  |  | | | ƒ }  q W|  S(   s¾   
        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.
        i   i   i    (   R   R   R   (   R,   R   R   R   R   (   R   (    s2   lib/python2.7/site-packages/numba/tests/timsort.pyR   D  s    	"c         ` s¾   | } | d } xA | | k  rS |  | |  | |  | <|  | <| d 7} | d 8} q Wˆ  |  | ƒ rº | } | d } xD | | k  r¶ | | | | | | <| | <| d 7} | d 8} qv Wn  d S(   s,   
        Reverse a slice, in-place.
        i   N(    (   R   R   R   RC   RP   t   j(   R   (    s2   lib/python2.7/site-packages/numba/tests/timsort.pyt   reverse_sliceW  s    



c   	      ` sM  t  | ƒ } | d k  r d Sˆ | ƒ } ˆ } xÌ | d k rü ˆ | | | | ƒ \ } } | ry ˆ | | | | | ƒ n  | | k  r» t | | ƒ } ˆ  | | | | | | | ƒ | } n  ˆ |  t | | ƒ ƒ }  ˆ |  | | ƒ }  | | 7} | | 8} q1 Wˆ |  | | ƒ }  |  j d k s$t ‚ |  j d d t  | ƒ f k sIt ‚ d S(   s2   
        Run timsort with the mergestate.
        i   Ni    i   (   R    R   R   R   R+   R   (	   R,   R   R   t
   nremainingt   minrunR7   R   t   desct   force(   R   R   R   R   R   R   R`   R)   (    s2   lib/python2.7/site-packages/numba/tests/timsort.pyt   run_timsort_with_mergestatek  s(    	
c         ` s    |  } ˆ ˆ  |  ƒ |  | ƒ d S(   s2   
        Run timsort over the given keys.
        N(    (   R   R   (   R
   Re   (    s2   lib/python2.7/site-packages/numba/tests/timsort.pyR     s    c         ` s   ˆ ˆ  |  | ƒ |  | ƒ d S(   s=   
        Run timsort over the given keys and values.
        N(    (   R   R   (   R*   Re   (    s2   lib/python2.7/site-packages/numba/tests/timsort.pyR   ™  s    (   R   R'   R   (   t   wrapR(   R   R   (    (   R^   R5   R   R   R   R	   R   R'   R(   R2   R   R   R   R   R   R0   R   R
   R*   R   R   R`   Re   RQ   RR   R)   s2   lib/python2.7/site-packages/numba/tests/timsort.pyt   make_timsort_impl:   sF    	
2%VL*›-ž!0*%		c          G` s   t  d „  |  Œ S(   Nc         S` s   |  S(   N(    (   t   f(    (    s2   lib/python2.7/site-packages/numba/tests/timsort.pyt   <lambda>«  t    (   Rg   (   t   args(    (    s2   lib/python2.7/site-packages/numba/tests/timsort.pyt   make_py_timsortª  s    c          ` s&   d d l  m ‰  t ‡  f d †  |  Œ S(   Ni    (   t   jitc         ` s   ˆ  d t  ƒ |  ƒ S(   Nt   nopython(   R@   (   Rh   (   Rm   (    s2   lib/python2.7/site-packages/numba/tests/timsort.pyRi   ¯  Rj   (   t   numbaRm   Rg   (   Rk   (    (   Rm   s2   lib/python2.7/site-packages/numba/tests/timsort.pyt   make_jit_timsort­  s    (   t   __doc__t
   __future__R    R   R   t   collectionsRo   R   t
   namedtupleR   R"   R#   R!   R   R   Rg   Rl   Rp   (    (    (    s2   lib/python2.7/site-packages/numba/tests/timsort.pyt   <module>   s.   			ÿ ÿ ÿ s	