
    6hߗ                    r   S SK Jr  SSKJrJrJr  S SKJrJrJ	r	J
r
JrJrJrJrJrJrJr  SSKJrJrJrJrJr  SSKJrJr  \(       a  SSKJr  \/(       d   e\R8                  r " S S	5      rS
 rS r " S S5      r Sr!Sr"Sr# " S S\ 5      r$SS jr%S r& " S S\$5      r' " S S\$5      r( " S S\ 5      r)g)    )annotations   )binhexnullrev)AnyCallableDictIterableListOptionalSetTYPE_CHECKINGTupleUnioncast)encodingerrorobsoletescmutilutil)repoviewutil
stringutil)	localrepoc                  F    \ rS rSrSrS rS rSS jrS rS r	S r
S	 rS
rg)BranchMapCache3   z8mapping of filtered views of repo with their branchcachec                    0 U l         g N_per_filterselfs    5/usr/lib/python3/dist-packages/mercurial/branchmap.py__init__BranchMapCache.__init__6   s
        c                    U R                  U5        U R                  UR                     nUR                  U5        UR                  UR                  :X  d   UR                  UR                  45       eU$ r   )updatecacher!   
filtername_ensure_populated_filtername)r#   repobcaches      r$   __getitem__BranchMapCache.__getitem__9   sm    !!$//2  &!!T__4 	
OO7
 	
4 r'   c                ^   U R                  U5        U R                  UR                     nUR                  UR                  :X  d   UR                  UR                  45       eU(       a  UR	                  U5        UR                  5       n[        USS5      (       a  UR                  U5        gg)a  ensure and up-to-date cache is (or will be) written on disk

The cache for this repository view is updated  if needed and written on
disk.

If a transaction is in progress, the writing is schedule to transaction
close. See the `BranchMapCache.write_dirty` method.

This method exist independently of __getitem__ as it is sometime useful
to signal that we have no intend to use the data in memory yet.
	finalizedTN)r)   r!   r*   r,   _detect_pure_topocurrenttransactiongetattr	sync_disk)r#   r-   detect_pure_topor.   trs        r$   update_diskBranchMapCache.update_diskC   s     	!!$//2!!T__4 	
OO7
 	
4 $$T*$$&2{D))T" *r'   c                  ^ UR                   nUR                  nU R                  R                  U5      mTb  TR	                  U5      (       d  [        U5      m/ nTc  [        R                  U5      nUb  UR                  U5      nU R                  U5        U R                  UR                     R                  U5      mUR                   R                  UR                  -
  nUR                  U4S jU 5       5        O[        U5      mUR                  UR                  TR                  S-   S95        U(       a  TR                  X5        TR	                  U5      (       d   U5       eTU R                  UR                  '   g)z<Update the cache for the given filtered view on a repositoryNc              3  J   >#    U  H  oTR                   ::  d  M  Uv   M     g 7fr   )tiprev).0rr.   s     r$   	<genexpr>-BranchMapCache.updatecache.<locals>.<genexpr>s   s     Gy!4FAAy   #	#r   )start)	changelogr*   r!   getvalidforbranch_cache_from_filesubsettablefilteredr)   inherit_forfilteredrevsextendnew_branch_cacherevsr=   update)	r#   r-   clr*   rN   
subsetnamesubset	extrarevsr.   s	           @r$   r)   BranchMapCache.updatecache[   s<    ^^__
!!%%j1>!6!6+D1F> %4J%z2  ())&*;*;<HHN",,99BOOK	GyGG *$/BGG&--!"3G45MM$%t$$0j0$,2)r'   c                >  ^ UR                   nUR                  mUR                  n/ n[        5       nUR	                  5        H<  nXW-  nU H/  nT" U5      n	U" U	5      u  pU(       d  M  UR                  U5        M1     M>     U(       a  [        U4S jU 5       5      n[        UUX   R                  5       UUS9nS H\  nUR                  U5      nUR                  U5      (       d  M,  Xl        XR                  U'   [        Ul        UR                  U5          g   gg)zReplace the branchmap cache for a repo with a branch mapping.

This is likely only called during clone with a branch map from a
remote.

c              3  F   >#    U  H  n[        T" U5      5      v   M     g 7fr   )int)r>   nodeclrevs     r$   r@   )BranchMapCache.replace.<locals>.<genexpr>   s     ?wt#eDk**w   !)closednodes)s   bases	   immutables   servedN)rD   rev
branchinfosetvaluesaddmaxrM   rX   rI   rF   r,   r!   STATE_DIRTY_statewrite)r#   r-   remotebranchmaprP   clbranchinforbheadsclosedbheadshr?   bcrtiprevcache	candidaterviewrY   s                   @r$   replaceBranchMapCache.replace   s    ^^}}%,,.FG!H#A1JJqM	  / ?w??G$""$"E @	i0>>%(((1%27$$Y/#.ELKK& @ r'   c                8    U R                   R                  5         g r   )r!   clearr"   s    r$   ru   BranchMapCache.clear   s     r'   c                    UR                  5       n[        R                  " 5        HK  nU R                  R	                  U5      nUc  M#  Uc  UnOUR                  U5      nUR                  U5        MM     g r   )
unfilteredr   get_ordered_subsetr!   rE   rI   r6   )r#   r-   unfir*   ro   s        r$   write_dirtyBranchMapCache.write_dirty   sd     &99;J$$((4E}!}}Z0OOD! <r'   r    NF)__name__
__module____qualname____firstlineno____doc__r%   r/   r9   r)   rr   ru   r{   __static_attributes__ r'   r$   r   r   3   s*    B#0"3H'R!
"r'   r   c                :    [        SU R                  5       -  5      e)zEraises ValueError when branchcache found a node which does not existsznode %s does not exist)
ValueErrorr   rX   s    r$   _unknownnoder      s    
-
:
;;r'   c                <    U R                   b  SU R                   -  $ g)Ns   branch cache (%s)s   branch cache)r*   r-   s    r$   _branchcachedescr      s    "#doo55r'   c                      \ rS rSrSr  S       SS jjrS rS rS rS r	S	 r
\
rS
 rS rS rS rSS jrS rS rS rS rSrg)_BaseBranchCache   zA dict like object that hold branches heads cache.

This cache is used to avoid costly computations to determine all the
branch heads of a repo.
Nc                ^    Uc
  [        5       n[        U5      U l        [        U5      U l        g)hasnode is a function which can be used to verify whether changelog
has a given node or not. If it's not provided, we assume that every node
we have exists in changelogN)r_   _closednodesdict_entries)r#   r-   entriesclosed_nodess       r$   r%   _BaseBranchCache.__init__   s)     5L-Wr'   c                ,    [        U R                  5      $ r   )iterr   r"   s    r$   __iter___BaseBranchCache.__iter__   s    DMM""r'   c                     X R                   U'   g r   r   )r#   keyvalues      r$   __setitem___BaseBranchCache.__setitem__   s    "cr'   c                     U R                   U   $ r   r   r#   r   s     r$   r/   _BaseBranchCache.__getitem__   s    }}S!!r'   c                    XR                   ;   $ r   r   r   s     r$   __contains___BaseBranchCache.__contains__   s    mm##r'   c                6    U R                   R                  5       $ r   )r   itemsr"   s    r$   	iteritems_BaseBranchCache.iteritems   s    }}""$$r'   c                    XR                   ;   $ z2checks whether a branch of this name exists or notr   )r#   labels     r$   	hasbranch_BaseBranchCache.hasbranch   s    %%r'   c                h    US   nSn[        U5       H  nX@R                  ;  d  M  UnSn  X#4$    X#4$ )z`Return tuple with last open head in heads and false,
otherwise return last closed head and true.TF)reversedr   )r#   headstipri   rk   s        r$   
_branchtip_BaseBranchCache._branchtip   sK     Bi%A))){ !
 {r'   c                .    U R                  X   5      S   $ )zReturn the tipmost open head on branch head, otherwise return the
tipmost closed head on branch.
Raise KeyError for unknown branch.r   )r   )r#   branchs     r$   	branchtip_BaseBranchCache.branchtip   s     t|,Q//r'   c                   ^  U 4S jU 5       $ )Nc              3  J   >#    U  H  oTR                   ;  d  M  Uv   M     g 7fr   r   r>   nr#   s     r$   r@   ,_BaseBranchCache.iteropen.<locals>.<genexpr>  s     ?5aT->->$>5rB   r   )r#   nodess   ` r$   iteropen_BaseBranchCache.iteropen  s    ?5??r'   c                f    U R                   U   nU(       d  [        U R                  U5      5      nU$ r   )r   listr   )r#   r   ri   r   s       r$   branchheads_BaseBranchCache.branchheads  s+    f%u-.Er'   c              #  l   #    U R                  5        H  u  pX4U R                  U5      -   v   M     g 7fr   )r   r   )r#   bnr   s      r$   iterbranches_BaseBranchCache.iterbranches  s-     IB+ 666 &s   24c                6    U R                   R                  5       $ zreturns all the heads)r   r`   r"   s    r$   	iterheads_BaseBranchCache.iterheads  s    }}##%%r'   c                  ^ [         R                  " 5       nUR                  m[        R                  " US5      n0 n[        5       n[        5       nUR                  5       R                  nSn	U Hk  n
[        X5      n	X;   a  UR                  U
5        M&  U" U
5      u  pUR                  U/ 5      R                  U
5        U(       d  MZ  UR                  U
5        Mm     U	S:  a  Sn[        R                  " U5      eU R                  UUUUU	5        U R                  R!                  U4S jU 5       5        [         R                  " 5       U-
  nUR"                  R%                  SS['        U5      U5        U	$ )zGiven a branchhead cache, self, that may have extra nodes or be
missing heads, and a generator of nodes that are strictly a superset of
heads missing, this function updates self to be correct.
   obsoleter   r   z5running branchcache.update without revision to updatec              3  F   >#    U  H  nTR                  U5      v   M     g 7fr   r   )r>   r]   rP   s     r$   r@   *_BaseBranchCache.update.<locals>.<genexpr><  s      D#r[      branchcaches   updated %s in %.4f seconds
)r   timerrD   r   getrevsr_   revbranchcacher^   rb   ra   
setdefaultappendr   ProgrammingError_process_newr   rO   uilogr   )r#   r-   revgen	starttimeobsrevsnewbranches
new_closedobs_ignoredgetbranchinfomax_revr?   r   closesbranchmsgdurationrP   s                  @r$   rO   _BaseBranchCache.update  sI   
 JJL	^^""45U
e++-88A'oG| "#0#3 F""62.55a8|q!  Q;IC((--	
 	   D DD::<)++T"		
 r'   c                   SnUR                   nUR                  5       R                  n[        R                  " US5      n	UR
                  n
UR                  5        GH  u  pU R                  R                  U/ 5      nU Vs1 s H  oR                  U5      iM     nn[        5       n[        U5       GH   nU(       d  UR                  U5        M  U
" U5       Vs/ s H  nU[        :w  d  M  UPM     nn[        5       n[        5       n[        5       nU HU  nUU	;   a  UR                  U5        M  UU;   d  U" U5      S   U:X  a  UR                  U5        MD  UR                  U5        MW     [        U5      [        U5      s=:X  a  S:X  d$  O  UR                  U5        UR                  U5        UR!                  U5        UR                  U5        GM#     U(       a_  Uc  [        UR#                  5       5      nX-
  (       a:  [%        U5      nU['        U5      ::  a   [        UR)                  UU5      5      nUU-  nU(       d  GM  [        U5       Vs/ s H  nUR+                  U5      PM     snX'   GM     gs  snf s  snf s  snf )z2update the branchmap from a set of new informationNr   r   r   )rD   r   r^   r   r   _uncheckedparentrevsr   r   rE   r]   r_   sortedra   r   lenrO   difference_updateheadrevsminrb   	ancestorsrX   )r#   r-   r   r   r   r   	topoheadsrP   r   r   
parentrevsr   newheadrevsrj   rX   bheadset	uncertainnewrevpparents
samebranchotherbranch
obsparentsfloorrevr   r]   s                             r$   r   _BaseBranchCache._process_newG  s    	^^++-88""45 ,,
#.#4#4#6FH ]]&&vr2F178tH8I -LL(&0&8I&8AL1&8I U
!e U
 AG| #q)h-*:1*=*G"q)#* ! HZ=A=$$[1$$Z0**:6V$3 .6 $ #BKKM 2I'"8}H3y>1$'Y(I$J	 I-x8>x8HI8H8HIW $7J 9 J>  Js   I;J -J J)r   r   r   N)r-   localrepo.localrepositoryr   DUnion[Dict[bytes, List[bytes]], Iterable[Tuple[bytes, List[bytes]]]]r   Optional[Set[bytes]]returnNoner}   )r~   r   r   r   r   r%   r   r   r/   r   r   r   r   r   r   r   r   r   r   rO   r   r   r   r'   r$   r   r      s     -1&'&
& +& 
&&##"$% E&
0@7&/baJr'   r         c                  z  ^  \ rS rSr% SrSr\" \\   S5      r	S\
S'   SS\SSSSS4                   S U 4S jjjrS!S	 jrS
 rS"S jrS r\S 5       r\S#S j5       rS r\S 5       rS rS rS rS"S jrS$S jrS rS rU 4S jrU 4S jrU 4S jr\r U 4S jr!U 4S jr"S%U 4S jjr#U 4S jr$Sr%U =r&$ )&_LocalBranchCachei  z:base class of branch-map info for a local repo or repoviewNr   Tuple[bytes]_default_key_hashesFc
                  > UR                   U l        Uc  UR                  U l        OX0l        X@l        Uc  U R
                  U l        OXPl        [        U l        U	(       a  [        U l        [        T
U ]-  XUS9  Xl        [        5       U l        SU l        U R                  (       a  UR                   R"                  U l        gg)r   Nr-   r   r   )r*   r,   nullidtipnoder=   r
  
key_hashesSTATE_CLEANrd   STATE_INHERITEDsuperr%   _verify_noder_   _verifiedbranches_hasnoderD   hasnode)r#   r-   r   r  r=   r  r\   r  verify_node	inherited	__class__s             r$   r%   _LocalBranchCache.__init__  s    "  ???;;DL"L"66DO(O!)DKd+N (!$ NN22DM r'   c                    [         er   NotImplementedErrorr#   r-   s     r$   _compute_key_hashes%_LocalBranchCache._compute_key_hashes      !!r'   c                    g)6make sure any lazily loaded values are fully populatedNr   r  s     r$   r+   #_LocalBranchCache._ensure_populated  s    r'   c                    g r   r   r  s     r$   r3   #_LocalBranchCache._detect_pure_topo  s    r'   c                     UR                   R                  U R                  5      nU R                  U:w  a  gU R                  U5      nU R                  U:H  $ ! [         a     gf = f)zcheck that cache contents are valid for (a subset of) this repo

- False when the order of changesets changed or if we detect a strip.
- True when cache is up-to-date for the current repo or its subset.F)rD   rX   r=   
IndexErrorr  r  r  )r#   r-   rX   repo_key_hashess       r$   rF   _LocalBranchCache.validfor  si    
	>>&&t{{3D
 <<4 2248 /11  	 	s   %A 
A%$A%c                   S n UR                  U R                  U5      5      n[        U5      nU R                  X5      nU " U4SS0UD6nUR	                  U5      (       d  [        S5      eUR                  X5        U(       a  UR                  5         U$ ! [         a     U(       a  UR                  5         g g [         ah  nUR                  R                  (       aA  SnU[        U5      [        R                  " U5      4-  nUR                  R                  U5        S n S nANS nAff = f! U(       a  UR                  5         f f = f)Nr  Tztip differss   invalid %s: %s
)cachevfs	_filenamer   _load_headerrF   r   _load_headsOSErrorclose	Exceptionr   	debugflagr   r   forcebytestrdebug)clsr-   flineiterinit_kwargsr.   instr   s           r$   fromfile_LocalBranchCache.fromfile   s,   	cmmD12AAwH**4:K  F
 ??4(( //t. 	#  	 	   	ww  )$T*++D1  c"F	 	 s7   A9B 
D+ D. :	D+AD&!D. &D++D. .Ec                    [         er   r  )r6  r-   r8  s      r$   r.  _LocalBranchCache._load_header#  s    !!r'   c                   U H  nUR                  S5      nU(       d  M  UR                  SS5      u  pEnUS;  a  [        S5      e[        R                  " UR                  5       5      n[        U5      nU R                  R                  U/ 5      R                  U5        US:X  d  M  U R                  R                  U5        M     g)Sfully loads the branchcache by reading from the file using the line
iterator passed   
    r  s   oczinvalid branch state   cN)rstripsplitr   r   tolocalstripr   r   r   r   r   ra   )r#   r-   r8  linerX   stater   s          r$   r/  _LocalBranchCache._load_heads'  s     D;;u%D!%D!!4DE! !788$$U[[]3Et9DMM$$UB/66t<}!!%%d+ r'   c                j    U R                   nUc   eUR                  (       a  SX!R                  4-  nU$ )z7name of a branchcache file for a given repo or repoviews   %s-%s)_base_filenamer*   )r6  r-   filenames      r$   r-  _LocalBranchCache._filename7  s8     %%###??8__"==Hr'   c                (   UR                   U R                  :w  d   e[        U 5      " UU R                  U R                  U R
                  U R                  [        U R                  5      U R                  SS9n[        U R                  5      Ul
        U$ )z,return a deep copy of the branchcache objectT)r-   r   r  r=   r  r\   r  r  )r*   r,   typer   r  r=   r  r_   r   r  r  )r#   r-   others      r$   rJ   _LocalBranchCache.inherit_for@  s}    $"2"2222T
 MMLL;;D--.))
 #&d&<&<"=r'   c                    U R                   [        :X  a  U R                  U5        gU R                   [        :X  a-  U R	                  U5      nUR
                  R                  U5        gg)a'  synchronise the on disk file with the cache state

If new value specific to this filter level need to be written, the file
will be updated, if the state of the branchcache is inherited from a
subset, any stalled on disk file will be deleted.

That method does nothing if there is nothing to do.
N)rd   rc   re   r  r-  r,  	tryunlink)r#   r-   rM  s      r$   r6   _LocalBranchCache.sync_diskT  sM     ;;+%JJt[[O+~~d+HMM##H- ,r'   c                ,   U R                   UR                  :X  d   U R                   UR                  45       eU R                  [        :X  d   U R                  5       eUR	                  5       n[        USS5      (       d  Sn[        R                  " U5      e U R                  U5      nUR                  USSS9 nU R                  U5        U R                  X5      nS S S 5        UR                  R                  SS[        U5      [        U R                   5      W5        ["        U l        g ! , (       d  f       NU= f! [$        [        R&                  4 a<  nUR                  R)                  S[*        R,                  " U5      -  5         S nAg S nAff = f)	Nr2   Tz2writing branchcache in the middle of a transaction   w)
atomictempr   s%   wrote %s with %d labels and %d nodes
s    couldn't write branch cache: %s
)r,   r*   rd   rc   r4   r5   r   r   r-  r,  _write_header_write_headsr   r   r   r   r   r  r0  Abortr5  r   r4  )r#   r-   r8   r   rM  r7  	nodecountr:  s           r$   re   _LocalBranchCache.writec  sX   4??2 	
OO5
 	
2 {{k)64;;6)$$&r;--FC((--	~~d+Hx$?1""1% --d6	 @ GGKK9 &DMM" &DK @? % 	GGMM4))$/0 	s1   "D= :#D,AD= ,
D:6D= =F2FFc                    [         er   r  )r#   fps     r$   rY  _LocalBranchCache._write_header  r!  r'   c                   Sn[        U R                  R                  5       5       H\  u  pE[        R                  " U5      nU H;  nUS-  nX`R
                  ;   a  SnOSnUR                  S[        U5      Xt4-  5        M=     M^     U$ )Bwrite list of heads to a file

Return the number of heads written.r   r   rC     o	   %s %s %s
)r   r   r   r   	fromlocalr   re   r   )r#   r-   r_  r\  r   r   rX   rI  s           r$   rZ  _LocalBranchCache._write_heads  s     	"4==#6#6#89LE&&u-EQ	,,, E E#d)U)BBC  : r'   c                ,   U R                   (       d  gXR                  ;  d  XR                  ;   a  gU R                  c   eU R                  U    H&  nU R                  U5      (       a  M  [	        U5        M(     U R                  R                  U5        g)z'verify head nodes for the given branch.N)r  r   r  r  r   ra   )r#   r   r   s      r$   _verifybranch_LocalBranchCache._verifybranch  su      &&4J4J*J}}(((v&A==##Q ' 	""6*r'   c                    U R                   R                  5        H%  nXR                  ;  d  M  U R                  U5        M'     g)z"verifies nodes of all the branchesN)r   keysr  rh  )r#   rl   s     r$   
_verifyall_LocalBranchCache._verifyall  s3    ##%A...""1% &r'   c                D   > U R                  U5        [        TU ]	  U5      $ r   )rh  r  r/   r#   r   r  s     r$   r/   _LocalBranchCache.__getitem__  s!    3w"3''r'   c                D   > U R                  U5        [        TU ]	  U5      $ r   )rh  r  r   ro  s     r$   r   _LocalBranchCache.__contains__  s!    3w#C((r'   c                @   > U R                  5         [        TU ]	  5       $ r   )rl  r  r   r#   r  s    r$   r   _LocalBranchCache.iteritems  s    w ""r'   c                @   > U R                  5         [        TU ]	  5       $ r   )rl  r  r   rt  s    r$   r   _LocalBranchCache.iterheads  s    w ""r'   c                D   > U R                  U5        [        TU ]	  U5      $ r   )rh  r  r   )r#   r   r  s     r$   r   _LocalBranchCache.hasbranch  s!    5!w ''r'   c                @   > U R                  U5        [        TU ]	  XS9$ )N)ri   )rh  r  r   )r#   r   ri   r  s      r$   r   _LocalBranchCache.branchheads  s$    6"w"6"99r'   c                  > U R                   UR                  :X  d   U R                   UR                  45       eUR                  n[        TU ]  X5      nUb,  X@R
                  :  a  X@l        UR                  U5      U l        O+UR                  U R
                  5      U R                  :X  d   eU R                  U5      (       d<  U R                  U5      U l
        [        R                  " UU R
                  5      U l        [        U l        UR!                  5       n[#        USS5      (       a  U R%                  U5        g g )Nr2   T)r,   r*   rD   r  rO   r=   rX   r  rF   r  r  r   #combined_filtered_and_obsolete_hashfilteredhashrc   rd   r4   r5   re   )r#   r-   r   rP   r   r8   r  s         r$   rO   _LocalBranchCache.update  s   4??2 	
OO5
 	
2 ^^'.. 7[[#8!K777+DL 774;;'4<<777}}T"" #66t<DO ' K K!D
 "$$&2{D)) JJt	 *r'   )	r,   r  rd   r  r  r~  r  r  r=   )r-   r   r   r  r  zOptional[bytes]r=   zOptional[int]r  zOptional[Tuple[bytes]]r\   r  r  z!Optional[Callable[[bytes], bool]]r  boolr  r  r  r  r  r	  r  r  r  zdict[str, Any]r  rW   r}   )'r~   r   r   r   r   rL  r   r   bytesr
  __annotations__r   r%   r  r+   r3   rF   classmethodr;  r.  r/  r-  rJ   r6   re   rY  rZ  rh  rl  r/   r   r   r   r   r   r   rO   r   __classcell__r  s   @r$   r  r    sQ   DN(,U5\2(>> #' '-1,059!*3'*3
*3 !*3 *3 +*3 **3 3*3 *3 *3 
*3 *3X"E2*    D " ",   (.>" +&()# E#
(
:$ $r'   r  c                    U R                   R                  SS5      (       a  [        R                  U 5      $ [        R                  U 5      $ )z{Build a branch cache from on-disk data if possible

Return a branch cache of the right format depending of the repository.
   experimental   branch-cache-v3)r   
configboolBranchCacheV3r;  BranchCacheV2r   s    r$   rG   rG     s>    
 ww/+=>>%%d++%%d++r'   c                    U R                   R                  SS5      (       a  [        U /UQ70 UD6$ [        U /UQ70 UD6$ )zoBuild a new branch cache from argument

Return a branch cache of the right format depending of the repository.
r  r  )r   r  r  r  )r-   argskwargss      r$   rM   rM     sF    
 ww/+=>>T3D3F33T3D3F33r'   c                  D    \ rS rSrSrSr\S	S j5       rS
S jrSS jr	Sr
g)r  i  a  a branch cache using version 2 of the format on disk

The cache is serialized on disk in the following format:

<tip hex node> <tip rev number> [optional filtered repo hex hash]
<branch head hex node> <open/closed state> <branch name>
<branch head hex node> <open/closed state> <branch name>
...

The first line is used to check if the cache is still valid. If the
branch cache is for a filtered repo view, an optional third hash is
included that hashes the hashes of all filtered and obsolete revisions.

The open/closed state is represented by a single letter 'o' or 'c'.
This field can be used to avoid changelog reads when determining if a
branch head closes a branch or not.
s   branch2c                    [        U5      R                  S5      R                  SS5      nUSS u  pE[        U5      [	        U5      pTSn[        U5      S:  a  [        US   5      4nUUUS.$ )zaparse the head of a branchmap file

return parameters to pass to a newly created class instance.
rA  rB  r  Nr   )r  r=   r  )nextrD  rE  r   rW   r   )r6  r-   r8  cachekeylastlrevr~  s          r$   r.  BranchCacheV2._load_header  sv     >((/55dA>bq\
YD	dx=1,.L&
 	
r'   c                   [        U R                  5      SU R                  -  /nU R                  (       a'  UR	                  [        U R                  S   5      5        UR                  SR                  U5      S-   5        g)z'write the branch cache header to a file   %dr   rB  rA  N)r   r  r=   r  r   re   join)r#   r_  r  s      r$   rY  BranchCacheV2._write_header(  sY    %ut{{':;??OOC 234
8$u,-r'   c                    [         R                  " UU R                  SS9n[        [        [
           S5      nUb  U4nU$ ):return the cache key hashes that match this repoview stateT)needobsoleter   )r   r}  r=   r   r   r  )r#   r-   filtered_hashrk  s       r$   r  !BranchCacheV2._compute_key_hashes/  sD    CCKK

 "%,3$"/!1Dr'   r   Nr  r  r  )r~   r   r   r   r   rL  r  r.  rY  r  r   r   r'   r$   r  r    s*    $  N
 
".
r'   r  c                     ^  \ rS rSrSrSrSrSS.U 4S jjrU 4S jrS	 r	SS
 jr
SS jr\S 5       rU 4S jrSS jr  SU 4S jjrS rSS jrSrU =r$ )r  i<  u  a branch cache using version 3 of the format on disk

This version is still EXPERIMENTAL and the format is subject to changes.

The cache is serialized on disk in the following format:

<cache-key-xxx>=<xxx-value> <cache-key-yyy>=<yyy-value> […]
<branch head hex node> <open/closed state> <branch name>
<branch head hex node> <open/closed state> <branch name>
...

The first line is used to check if the cache is still valid. It is a series
of key value pair. The following key are recognized:

- tip-rev: the rev-num of the tip-most revision seen by this cache
- tip-node: the node-id of the tip-most revision sen by this cache
- filtered-hash: the hash of all filtered revisions (before tip-rev)
                 ignored by this cache.
- obsolete-hash: the hash of all non-filtered obsolete revisions (before
                 tip-rev) ignored by this cache.

The tip-rev is used to know how far behind the value in the file are
compared to the current repository state.

The tip-node, filtered-hash and obsolete-hash are used to detect if this
cache can be used for this repository state at all.

The open/closed state is represented by a single letter 'o' or 'c'.
This field can be used to avoid changelog reads when determining if a
branch head closes a branch or not.

Topological heads are not included in the listing and should be dispatched
on the right branch at read time. Obsolete topological heads should be
ignored.
s   branch3-exp)NNN)pure_topo_branchc               X   > [         TU ]  " U0 UD6  Xl        U R                  S LU l        g r   )r  r%   _pure_topo_branch_needs_populate)r#   r  r  r  r  s       r$   r%   BranchCacheV3.__init__d  s.    $)&)!1#55TAr'   c                j   > [         TU ]  U5      nU R                  Ul        U R                  Ul        U$ r   )r  rJ   r  r  )r#   r-   newr  s      r$   rJ   BranchCacheV3.inherit_fori  s3    g!$' $ 6 6"22
r'   c                    UR                   nU R                  [        :X  a  / $ U R                  UR                  5       :X  a  UR                  5       $ UR                  U R                  S-   S9nU$ )zDreturns the topological head of a repoview content up to self.tiprevr   )stop_rev)rD   r=   r   r   )r#   r-   rP   r   s       r$   _get_topo_headsBranchCacheV3._get_topo_headso  sW    ^^;;'!I[[BIIK';;= KKqK9ELr'   c                J   [        U R                  5      SU R                  -  S.nU R                  (       aV  U R                  S   b  [        U R                  S   5      US'   U R                  S   b  [        U R                  S   5      US'   U R                  b  SUS'   S	 [        UR                  5       5       5       nUR                  S
R                  U5      S-   5        U R                  b5  [        R                  " U R                  5      nUR                  US-   5        g g )Nr  )   tip-node   tip-revr      filtered-hashr      obsolete-hash   pure	   topo-modec              3  ,   #    U  H
  nS U-  v   M     g7f)s   %s=%sNr   )r>   is     r$   r@   .BranchCacheV3._write_header.<locals>.<genexpr>  s     C(B1(Q,(Bs   rB  rA  )r   r  r=   r  r  r   r   re   r  r   re  )r#   r_  
cache_keyspiecesr   s        r$   rY  BranchCacheV3._write_headerz  s    T\\*+

 ??q!-/24??13E/F
+,q!-/24??13E/F
+,!!-'.J|$Cz/?/?/A(BC
6"U*+!!-&&t'='=>EHHUU]# .r'   c                   UR                   R                  nSnSnU R                  c&  U R                  U5       Vs1 s H
  oc" U5      iM     nn[	        U R
                  R                  5       5       Hw  u  pxXpR                  :X  a  M  [        R                  " U5      nU HE  n	Ub  X;   a  M  XR                  ;   a  Sn
OSn
US-  nUR                  S[        U	5      X4-  5        MG     My     U$ s  snf )rb  r   NrC  rc  r   rd  )rD   rX   r  r  r   r   r   r   re  r   re   r   )r#   r-   r_  to_noder\  
topo_headsr?   r   r   rX   rI  s              r$   rZ  BranchCacheV3._write_heads  s     ..%%	
!!) /3.B.B4.HI.H'!*.HJI"4==#6#6#89LE...&&u-E)) ,,, E EQ	#d)U)BBC  : ! Js   C.c                   [        U5      nUR                  S5      R                  S5      nU H  nSU;  d  M  SU-  n[        U5      e   [	        S U 5       5      n0 nS n	S n
SnUR                  5        H  u  pUS:X  a  [        U5      US'   M  US	:X  a  [        U5      US
'   M1  US:X  a  [        U5      n	MD  US:X  a  [        U5      n
MW  US:X  a  US:X  a  SnMg  SU-  n[        U5      eSU-  n[        U5      e   X4US'   U(       a3  [        U5      R                  S5      n[        R                  " U5      US'   U$ )NrA  rB     =s   invalid header_line: %rc              3  D   #    U  H  oR                  S S5      v   M     g7f)r  r   N)rE  )r>   r   s     r$   r@   -BranchCacheV3._load_header.<locals>.<genexpr>  s     ;Fq''$**Fs    Fr  r=   r  r  r  r  r  r  Ts   unknown topo-mode: %rs   unknown cache key: %rr  r  )
r  rD  rE  r   r   r   rW   r   r   rF  )r6  r-   r8  header_liner  r   r   r  r  r  obsolete_hashhas_pure_topo_headskv	pure_lines                  r$   r.  BranchCacheV3._load_header  sR   8n##E*006A1}0;> o%  ;F;;
#$$&DAJ!$QXk!"%a&Y&& #A&& #Al"<*.'2Q6C$S/).2 o%# '$ ,;\X--e4I'/'7'7	'BD#$r'   c                z  > [         TU ]  X5        U R                  b  gUR                  nUR	                  5       R
                  n[        R                  " US5      nUR                  n[        5       nU R                  U5       Hz  nX;   a  M
  U" U5      n	U" U5      u  pU R                  R                  U
/ 5      R                  U	5        U(       a  U R                  R                  U	5        UR                  U
5        M|     UR                   R"                  nU H  n
U R                  U
   R%                  US9  M!     g)r@  Nr   )r   )r  r/  r  rD   r   r^   r   r   rX   r_   r  r   r   r   r   ra   indexr]   sort)r#   r-   r8  rP   r   r   r  touched_branchheadrX   r   ri   to_revr  s                r$   r/  BranchCacheV3._load_heads  s	    	D+!!-^^++-88""45''((.D4=D*40NFMM$$VR077=!!%%d+v& / $FMM&!&&6&2 %r'   c                D    [         R                  " UU R                  5      $ )r  )r   filtered_and_obsolete_hashr=   r  s     r$   r  !BranchCacheV3._compute_key_hashes  s    11KK
 	
r'   c                  > U(       d  U(       d  U(       a3  [        U5      S:X  a  U R                  [        :X  d  U R                  U;   ag  U(       a_  [        U5      S:X  d   e[	        UR                  5       5      S   U l        SU l        U R                  R                  U R                  S 5        g U R                  U5        S U l        [        TU ]-  UUUUU5        g )Nr   r   T)r   r=   r   r  r   rk  r  r   popr+   r  r   )r#   r-   r   r   r   r   r  s         r$   r   BranchCacheV3._process_new  s      
$)w.11[@
 ;'1,,,)-k.>.>.@)A!)D&'+$!!$"8"8$?t$!%	
r'   c                   U R                   (       ao  U R                  c   eUR                  nUR                  nU R	                  U5      nU Vs/ s H
  oS" U5      PM     nnX`R
                  U R                  '   SU l         ggs  snf )r#  NF)r  r  rD   rX   r  r   )r#   r-   rP   r  r  r?   r   s          r$   r+   BranchCacheV3._ensure_populated  s{    ))555BggG--d3J)34AWQZE449MM$001#(D   
 5s   Bc                R  ^  T R                   b  g UR                  R                  nT R                  U5       Vs/ s H
  o2" U5      PM     nn[	        U 4S jU 5       5      (       a  g T R
                  R                  5        H  u  pVXd:X  d  M  UT l         [        T l          g    g s  snf )Nc              3  @   >#    U  H  oTR                   ;   v   M     g 7fr   r   r   s     r$   r@   2BranchCacheV3._detect_pure_topo.<locals>.<genexpr>,  s     :z!D%%%zs   )	r  rD   rX   r  anyr   r   rc   rd   )r#   r-   r  r?   r  r   r   s   `      r$   r3   BranchCacheV3._detect_pure_topo&  s    !!-..%%*.*>*>t*DE*DQgaj*D
E:z:::!]]002MF")/&)	 3 Fs   B$)r  r  rd   r  r  r  )r~   r   r   r   r   rL  r
  r%   rJ   r  rY  rZ  r  r.  r/  r  r   r+   r3   r   r  r  s   @r$   r  r  <  sw    "H $N&/3 B B
	$$8 # #J32
+
 
+
Z	) r'   r  c                  F   ^  \ rS rSrSr  S       SU 4S jjjrSrU =r$ )remotebranchcachei5  z@Branchmap info for a remote connection, should not write locallyr   c                "   > [         TU ]  XUS9  g )Nr  )r  r%   )r#   r-   r   r\   r  s       r$   r%   remotebranchcache.__init__8  s     	d+Nr'   r   )r-   r   r   r  r\   r  r  r  )r~   r   r   r   r   r%   r   r  r  s   @r$   r  r  5  sD    J ,0O'O
O *O 
O Or'   r  N)r  zOptional[_LocalBranchCache])*
__future__r   rX   r   r   r   typingr   r	   r
   r   r   r   r   r   r   r   r    r   r   r   r   r   utilsr   r   r   rH   r   r   r   r   r  r  rc   r  rG   rM   r  r  r  r   r'   r$   <module>r     s    #     
 ;;&&B" B"J<
dJ dJN x( xv	,48% 8vv% vrO( Or'   