
    6h                    X    S r SSKJr  SSKrSSKJr  SSKJr  S rS r	S	 r
S
 rS rS rg)a  
Stable-tail sort computation.

The "stable-tail sort", or STS, is a reverse topological ordering of the
ancestors of a node, which tends to share large suffixes with the stable-tail
sort of ancestors and other nodes, giving it its name.

Its properties should make it suitable for making chunks of ancestors with high
reuse and incrementality for example.

This module and implementation are experimental. Most functions are not yet
optimised to operate on large production graphs.
    )annotationsN   )nullrev)ancestorc                    U R                  U5      U R                  U5      pCX4:  a  X4$ X4:  a  X!4$ U R                  U5      U R                  U5      :  a  X4$ X!4$ )a  
Chooses and returns the pair (px, pt) from (p1, p2).

Where
"px" denotes the parent starting the "exclusive" part, and
"pt" denotes the parent starting the "Tail" part.

"px" is chosen as the parent with the lowest rank with the goal of
minimising the size of the exclusive part and maximise the size of the
tail part, hopefully reducing the overall complexity of the stable-tail
sort.

In case of equal ranks, the stable node ID is used as a tie-breaker.
)	fast_ranknode)clp1p2r1r2s        J/usr/lib/python3/dist-packages/mercurial/stabletailgraph/stabletailsort.py_sorted_parentsr      s[     \\"r||B/	wx	x	rwwr{	"xx    c                   U R                  U5      u  p#U[        :X  d'  U R                  U5      U R                  U5      S-
  :X  a  U[        4$ U[        :X  d'  U R                  U5      U R                  U5      S-
  :X  a  U[        4$ X#4$ )u   
Returns the non-œdipal parent pair of the given revision.

An œdipal merge is a merge with parents p1, p2 with either
p1 in ancestors(p2) or p2 in ancestors(p1).
In the first case, p1 is the œdipal parent.
In the second case, p2 is the œdipal parent.

Œdipal edges start empty exclusive parts. They do not bring new ancestors.
As such, they can be skipped when computing any topological sort or any
iteration over the ancestors of a node.

The œdipal edges are eliminated here using the rank information.
   )
parentrevsr   r   r
   revr   r   s       r   _nonoedipal_parent_revsr   7   sy     ]]3FB	W}R(BLL,=,AA7{	w",,r*bll3.?!.CC7{vr   c                N    [        X5      u  p#U[        :X  a  X#4$ [        XU5      $ N)r   r   r   r   s       r   _parentsr   O   s)    $R-FB	W}v22&&r   c              #  x  ^#    UnU[         :w  a  Uv   [        X5      u  p4U[         :X  a  UnO|[        R                  " U R                  U4SS9mU4S j[        X5       5       nU R                  U5      U R                  U5      -
  S-
  n[        R                  " XV5       Sh  vN   UnU[         :w  a  M  gg N7f)a  
Naive topological iterator of the ancestors given by the stable-tail sort.

The stable-tail sort of a node "h" is defined as the sequence:
sts(h) := [h] + excl(h) + sts(pt(h))
where excl(h) := u for u in sts(px(h)) if u not in ancestors(pt(h))

This implementation uses a call-stack whose size is
O(number of open merges).

As such, this implementation exists mainly as a defining reference.
T)	inclusivec              3  8   >#    U  H  nUT;  d  M  Uv   M     g 7fr    ).0atail_ancestorss     r   	<genexpr>*_stable_tail_sort_naive.<locals>.<genexpr>o   s"      #8AN* 8s   
	r   N)	r   r   r   lazyancestorsr   _stable_tail_sort_naiver   	itertoolsislice)r
   head_rev
cursor_revpxptexclusive_ancestorsexcl_part_sizer!   s          @r   r%   r%   W   s      J

")=J%33uN#08#  \\*5R8HH1LN ''(;LLLJ+ 
( Ms   B B:#B8$B:6B:c              #  |   #    [        X5      n[        U5      nU H  nU[        X5      S   :w  a  X44v   UnM     g7f)a   
Yields the leaps in the stable-tail sort of the given revision.

A leap is a pair of revisions (source, target) consecutive in the
stable-tail sort of a head, for which target != px(source).

Leaps are yielded in the same order as encountered in the stable-tail sort,
from head to root.
r   N)r%   nextr   )r
   r(   stsprevcurrents        r   _find_all_leaps_naiver3   }   sC      ""
/C9Dhr(++/!	 s   :<c              #    #    [        X5      u  p#U[        :X  d
  U[        :X  a  g[        [        X5      5      n[	        X5      n[        U5      nU H*  nXs:X  a    gU[        X5      S   :w  a  Xg4nX;  a  Uv   UnM,     g7f)a  
Returns the specific leaps in the stable-tail sort of the given revision.

Specific leaps are leaps appear in the stable-tail sort of a given
revision, but not in the stable-tail sort of any of its ancestors.

The final leaps (leading to the pt of the considered merge) are omitted.

Only merge nodes can have associated specific leaps.

This implementations uses the whole leap sets of the given revision and
of its parents.
Nr   )r   r   setr3   r%   r/   )	r
   r(   r*   r+   parents_leapsr0   r1   r2   leaps	            r   _find_specific_leaps_naiver8      s      b#FB	W}g-b56M
!"
/C9D=hr(++?D(
 s   A>B )__doc__
__future__r   r&   r	   r    r   r   r   r   r%   r3   r8   r   r   r   <module>r<      s7    #   40'#L&r   