
    q&fU                        d dl Z d dlZddlmZ ddlmZmZmZ ddlmZ	  G d de
      Zd	 Zd
 Zd Zd Z G d d      Zd Zd Zd,dZdZ ej*                  d      Z ej*                  d      Z G d d      Zd Zd Zd Zd Z ej*                  d      ZdZdZd Z d Z! G d de
      Z"d  Z#d! Z$d" Z%d-d#Z&d$ Z'd% Z(d& Z)d' Z*d( Z+d) Z,d* Z-d+ Z.y).    N   )hex)errorrequirementsutil   )docketc                       e Zd Zd Zy)NodeMapc                 2    t        j                  d|z        )Ns   unknown node: %s)r   RevlogError)selfxs     ?/usr/lib/python3/dist-packages/mercurial/revlogutils/nodemap.py__missing__zNodeMap.__missing__   s     3a 788    N)__name__
__module____qualname__r    r   r   r   r      s    9r   r   c                       y)zrhook point for test

    This let tests to have things happens between the docket reading and the
    data readingNr   r   r   r   test_race_hook_1r      s    
 	r   c                    t         j                  | j                   vryt         j                  | j                   v ry| j                         }t	        d||j
                         t	        d| |j                  j                  j                         y)zoThe stream clone might needs to remove some file if persisten nodemap
    was dropped while stream cloning
    N)	r   REVLOGV1_REQUIREMENTNODEMAP_REQUIREMENT
unfiltereddelete_nodemap	changelogmanifestlog
_rootstore_revlog)repounfis     r   post_stream_cleanupr$   $   sl     ((0A0AA''4+<+<<??D4t~~.4t//::BBCr   c                    | j                   y| j                  j                  | j                         }|syd}t        j	                  |||t        j
                  z          \  }|t        k7  ry|t        j
                  z  }t        j	                  |||t        j
                  z          }|\  }}}}}	|t        j
                  z  }t        ||||z          }
||z  }||
_	        ||||	z    |
_
        ||
_        ||
_        t        | |
      }| j                  j                  j                  d      }t!                	 | j                  |      5 }|r+	 t#        j$                  t#        j&                  ||            }n|j+                  |      }ddd       t/              |k  ry|
|fS # t(        $ r d}Y (w xY w# 1 sw Y   -xY w# t,        $ r Y yw xY w)z'read the nodemap for a revlog from diskNr      persistent-nodemap.mmapr   )_nodemap_fileopenertryread	S_VERSIONunpacksizeONDISK_VERSIONS_HEADERNodeMapDockettip_revtip_nodedata_lengthdata_unused_rawdata_filepathoptionsgetr   r   buffermmapread
ValueErrorreadFileNotFoundErrorlen)revlogpdataoffsetversionheadersuid_sizer0   r2   r3   tip_node_sizer	   filenameuse_mmapfddatas                  r   persisted_datarH   1   s   #MM!!&"6"67EF!!%)..1H"IJJW. 
innFooeFVhmm-CDEGAH>Hg{K
hmmF5&8*;<=F
hFFNFVm%;<FO$F$F 0H}}$$(()CDH]]8$ 	,;;t}}R'EFD
 ww{+	, 4y;4< " D		, 	,  sN   8G  	F4)F#6F4G  #F1.F40F11F44F=9G   	GGc                     j                   ryj                  ydj                  z  }| j                  |      ry| j                  |fd       | j	                  |fd       y)zInstall whatever is needed transaction side to persist a nodemap on disk

    (only actually persist the nodemap if this is relevant for this revlog)
    Ns   nm-revlog-persistent-nodemap-%sc                      t        | d      S )NT)pendingpersist_nodemaptrr=   s    r   <lambda>z*setup_persistent_nodemap.<locals>.<lambda>k   s    FD I r   c                     t        |       S NrL   rN   s    r   rP   z*setup_persistent_nodemap.<locals>.<lambda>m   s    ?2v+F r   )_inliner'   hasfinalize
addpendingaddfinalize)rO   r=   callback_ids    ` r   setup_persistent_nodemaprX   \   sb    
 ~~# 5v7K7KKK	~~k"MMI NN; FGr   c                   :    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
y	)
_NoTransactionzCtransaction like object to update the nodemap outside a transactionc                     i | _         y rR   
_postcloser   s    r   __init__z_NoTransaction.__init__s   s	    r   c                 "    || j                   |<   y rR   r\   )r   rW   callback_funcs      r   addpostclosez_NoTransaction.addpostclosev   s    '4$r   c                      y rR   r   r   argskwargss      r   registertmpz_NoTransaction.registertmpy       r   c                      y rR   r   rd   s      r   	addbackupz_NoTransaction.addbackup|   rh   r   c                      y rR   r   rd   s      r   addz_NoTransaction.add   rh   r   c                      y rR   r   rd   s      r   addabortz_NoTransaction.addabort   rh   r   c                      y rR   r   )r   re   s     r   _reportz_NoTransaction._report   rh   r   N)r   r   r   __doc__r_   rb   rg   rj   rl   rn   rp   r   r   r   rZ   rZ   p   s(    M5r   rZ   c                     | j                   ry| j                  yt               }t        ||        t	        |j
                        D ]  } |j
                  |   d        y)zupdate the persistent nodemap right now

    To be used for updating the nodemap on disk outside of a normal transaction
    setup (eg, `debugupdatecache`).
    N)rS   r'   rZ   rM   sortedr]   )r=   notrks      r   update_persistent_nodemaprv      sZ     ~~#DD&!DOO$ !4 !r   c                 0   |j                   }t        j                  d|z        }|j                  j	                  |j
                        }|j                  j                  |      D ]/  }|j                  |      s|j                  j                  |       1 y)z.Delete nodemap data on disk for a given revlogs"   (^|/)%s(-[0-9a-f]+\.nd|\.n(\.a)?)$N)
radixrecompiler(   dirname
_indexfilelistdirmatchsvfs	tryunlink)rO   r"   r=   prefixpatterndirpathfs          r   r   r      su    \\Fjj?&HIGmm##F$5$56G]]""7+ #==II"#r   c           	      	   t        |j                        dk  ryt        |dd      rt        j                  d      |j
                  *|rt        |      |_        nd}t        j                  |      t        |j                  d      }|j                  }t        |j                  d      }|j                  j                  j                  d	      }d}	|rR|O|j                  j                         }
|j                  j                         \  }}}	|
j                  t        |	      z   }|
j                  |z   }||
k7  rd}	n||d
z  k  rd}	nt!        ||
      | j#                  |
j                         |j                  d      5 }|j%                  |
j                         |j'                  |	       |r^|r:|j)                          t+        j,                  t+        j.                  ||            }n"|j%                  d       |j1                  |      }ddd       ||
_        ||
_        |	t3               }
t!        ||
      t        |j                  d      r|j                  j5                         }	nt7        |j                        }	|j                  j8                  fd}dz  }| j;                  ||       |j                  d      5 }|j'                  |	       |rG|r|	}nB|j)                          t+        j,                  t+        j.                  |t        |	                  }ddd       t        |	      |
_        |j=                         
_        |jA                  |
j>                        |
_!        |j
                  }|r|dz  }| jE                  |       n| jG                  |       |j                  |dd      5 }|j'                  |
jI                                ddd       |
|_        |r|j                  jK                  |
       tM        ||
      r?t        |d|j                        fd}d|j
                  z  }| jO                  ||       yy# 1 sw Y   IxY w# 1 sw Y   AxY w# 1 sw Y   xY w)z-Write nodemap data on disk for a given revlogr   Nfilteredrevsr   z.cannot persist nodemap of a filtered changelogz?calling persist nodemap on a revlog without the feature enablednodemap_data_incrementalupdate_nodemap_datar&   
   s   r+nodemap_data_allc                             y rR   r   )rO   datafiler   s    r   abortckz persist_nodemap.<locals>.abortck   s    hr   s	   delete-%ss   w+s   .a   wT)
atomictemp_realopenerc                 6    D ]  }j                  |        y rR   )r   )rO   oldfileoldsrealvfss     r   cleanupz persist_nodemap.<locals>.cleanup  s      +!!'*+r   s   revlog-cleanup-nodemap-%s)(r<   indexgetattrr   ProgrammingErrorr'   get_nodemap_filehasattr_nodemap_docketr(   r5   r6   copyr   r2   r3   r4   rl   seekwriteflushr   r7   r8   r:   r/   r   persistent_datar   rn   tiprevr0   noder1   rg   rj   	serializer   _other_rawdata_filepathrb   )rO   r=   rK   forcemsgcan_incrementalondisk_docket	feed_datarE   rG   target_docket
src_docketdata_changed_count
new_length
new_unusedrF   new_datar   rW   	file_pathfpr   r   r   r   r   s                         @@@@r   rM   rM      s   
6<<Av~r*$$<
 	
 ##3F#;F SC((--fll,FGO**M&;<I}}$$(()CDHD=4..335
 LL113		
"..T:
"..1CC
&DJO,D(?H FF8]667x/ 	72112
#';;t}}R/L#M
#%77:#6	7 )3M%(2M%|%$V];6<<!34<<002D"6<<0D MM++		  #X- 	K)]]8U+ 	IrHHTN#HHHJ#{{4==SY+GHH	I %(I!"MMOM#[[)>)>?M $$IU	
y!
Y	y$4	8 ,B
((*+,*F((A #6=9D&-?	+ 3V5I5II
W- 	7 	7D	I 	I(, ,s&   BQAQ(  Q5Q%(Q25Q>z>Bz>BQQQQc                   0    e Zd ZdZddZd Zd Zd Zd Zy)	r/   z}metadata associated with persistent nodemap data

    The persistent data may come from disk or be on their way to disk.
    Nc                 v    |t        j                         }|| _        d | _        d | _        d | _        d| _        y )Nr   )
docket_modmake_uiduidr0   r1   r2   r3   )r   r   s     r   r_   zNodeMapDocket.__init__7  sD    ;%%'C   
   r   c                     t        | j                        }| j                  |_        | j                  |_        | j                  |_        | j
                  |_        |S )N)r   )r/   r   r0   r1   r2   r3   )r   news     r   r   zNodeMapDocket.copyS  sE    )ll}}****
r   c                     | j                   |j                   k  ry| j                   |j                   kD  ry| j                  |j                  k  ry| j                  |j                  kD  ryy)Nr   r   r   r2   r   others     r   __cmp__zNodeMapDocket.__cmp__[  sY    88eii88eii 1 11 1 11r   c                 j    | j                   |j                   k(  xr | j                  |j                  k(  S rR   r   r   s     r   __eq__zNodeMapDocket.__eq__f  s+    xx599$N)9)9U=N=N)NNr   c                    g }|j                  t        j                  t                     t	        | j
                        | j                  | j                  | j                  t	        | j                        f}|j                  t        j                  |        |j                  | j
                         |j                  | j                         dj                  |      S )z9return serialized bytes for a docket using the passed uidr   )appendr*   packr-   r<   r   r0   r2   r3   r1   r.   join)r   rG   rA   s      r   r   zNodeMapDocket.serializei  s    INN>23MLL
 	HMM7+,DHHDMM"xx~r   rR   )	r   r   r   rq   r_   r   r   r   r   r   r   r   r/   r/   1  s!    
8	Or   r/   c                 <    | j                   }d||j                  fz  S )z9The (vfs relative) nodemap's rawdata file for a given uids   %s-%s.nd)rx   r   )r=   r	   r   s      r   r4   r4   z  s    \\F&&**---r   c                 h   | j                   }t        j                  d|z        }t        | |      }| j                  j                  |      }| j                  j                  |      }g }| j                  j                  |      D ]+  }|j                  |      s||k7  s|j                  |       - |S )Ns   (^|/)%s-[0-9a-f]+\.nd$)
rx   ry   rz   r4   r(   basenamer{   r}   r~   r   )	r=   r	   r   r   new_file_pathnew_file_namer   othersr   s	            r   r   r     s    \\Fjj3f<=G%ff5MMM**=9Mmm##M2GF]]""7+ ==] 2MM! Mr   c                 .    t        |       }t        |      S )zAreturn the persistent binary form for a nodemap for a given index)_build_trie_persist_trie)r   tries     r   r   r     s    uDr   c                 b    t        | ||      \  }}|t        j                  z  t        ||      fS )zGreturn the incremental update for persistent nodemap from a given index)existing_idx)_update_trieS_BLOCKr,   r   )r   rootmax_idxlast_revchanged_blockr   s         r   update_persistent_datar     s5    &udH=M4$d1 r   z>llllllllllllllllr   c                     | t         z    S )zReturn the number used to represent the rev in the tree.

    (or retrieve a rev number from such representation)

    Note that this is an involution, a function equal to its inverse (i.e.
    which gives the identity when applied to itself).
    )
REV_OFFSET)revs    r   _transform_revr     s     :r   c                     t        | d      S )z/turn an hexadecimal digit into a proper integer   )int)	hex_digits    r   _to_intr     s    y"r   c                   (     e Zd ZdZ fdZd Z xZS )BlockzOrepresent a block of the Trie

    contains up to 16 entry indexed from 0 to 15c                 8    t         t        |           d | _        y rR   )superr   r_   	ondisk_id)r   	__class__s    r   r_   zBlock.__init__  s    eT#%r   c                 >     t         fdt        d      D              S )Nc              3   @   K   | ]  }j                  |        y wrR   )r6   ).0ir   s     r   	<genexpr>z!Block.__iter__.<locals>.<genexpr>  s     3ADHHQK3s   r   )iterranger^   s   `r   __iter__zBlock.__iter__  s    3r333r   )r   r   r   rq   r_   r   __classcell__)r   s   @r   r   r     s    4
4r   r   c                     t               }t        t        |             D ]"  }t        | |   d         }t	        | d|||       $ |S )zbuild a nodemap trie

    The nodemap stores revision number for each unique prefix.

    Each block is a dictionary with keys in `[0, 15]`. Values are either
    another block or a revision number.
       r   )r   r   r<   r   _insert_into_block)r   r   r   current_hexs       r   r   r     sL     7DSZ  =%*Q-(5!T3<= Kr   c           	          d}t        |dz   t        |             D ]%  }t        | |   d         }|t        | d|||      z  }' ||fS )consumer   r   r   )r   r<   r   r   )r   r   r   changedr   r   s         r   r   r     s]    GX\3u:. H%*Q-(%eQc;GGH D=r   c                 `   d}|j                   d|_         t        |||dz          }|j                  |      }||||<   |S t        |t              r|t        | |dz   |||      z  }|S t        | |   d         }|}	t               }
|
||<   t        | |dz   |
|	|       t        | |dz   |
||       |S )a7  insert a new revision in a block

    index: the index we are adding revision for
    level: the depth of the current block in the trie
    block: the block currently being considered
    current_rev: the revision number we are adding
    current_hex: the hexadecimal representation of the of that revision
    r   Nr   )r   r   r6   
isinstancedictr   r   r   )r   levelblockcurrent_revr   r   r   entry	other_hex	other_revr   s              r   r   r     s     G"EEAI67IIIi E}&i N 
E4	 %519e[+
 	
 N eQ(		gi5%!)S)YG5%!)S+{KNr   c                    i }||dz   }nd}g }t        |       D ]\  }|j                  |j                  |t        |      <   (t        |      |z   |t        |      <   |j	                  t        ||             ^ dj                  |      S )zaturn a nodemap trie into persistent binary data

    See `_build_trie` for nodemap trie structurer   r   r   )
_walk_trier   idr<   r   _persist_blockr   )r   r   	block_mapbase_idxchunkstns         r   r   r     s     I!#F 9<<# "Ibf #Fh 6IbfMM.Y789 88Fr   c              #      K   t        | j                               D ]*  \  }}t        |t              st	        |      D ]  }|  , |  yw)zcyield all the block in a trie

    Children blocks are always yield before their parent block.
    N)rs   itemsr   r   r  )r   __item	sub_blocks       r   r  r  '  sP     
 U[[]+  
TdD!'-  	   Ks
   0AAc                 P    t        fd| D              }t        j                  | S )zproduce persistent binary data for a single block

    Children block are assumed to be already persisted and present in
    block_map.
    c              3   6   K   | ]  }t        |        y wrR   )	_to_value)r   vr  s     r   r   z!_persist_block.<locals>.<genexpr>9  s     =Q1i(=s   )tupler   r   )
block_noder  rG   s    ` r   r  r  3  s$     =*==D<<r   c                 d    | t         S t        | t              r|t        |          S t	        |       S )zpersist any value as an integer)NO_ENTRYr   r   r  r   )r  r  s     r   r  r  =  s0    |	D$	D""d##r   c                    t        |       t        j                  z  dk7  r3d}t        j                  |t        j                  t        |       fz        | st               dfS i }g }t        dt        |       t        j                        D ]i  }t               }t        |      |_        |||j                  <   | ||t        j                  z    }t        j                  |      }|j                  ||f       k |D ]>  \  }}t        |      D ]+  \  }	}
|
t        k(  r|
dk\  r	||
   ||	<   t        |
      ||	<   - @ t        j                  z  fS )z,parse parse nodemap data into a nodemap Trier   s:   nodemap data size is not a multiple of block size (%d): %dN)r<   r   r,   r   Abortr   r   r   r+   r   	enumerater  r   )rG   r   r  
new_blocksr   r   
block_datavaluesbidxr  s              r   
parse_datar  G  s:   D	GLL Q&Kkk#s4y 99::w}IJ1c$i. +i.%*	%//"!a',,./

+5&/*+   +	6' 	+FCH}a"1#'*#	++ !w||###r   c                 P   d}| j                  dt        |      z         t        |      \  }}t        t	        |            }| j                  dt        |      z         t        t        |            D ]  }||vrd|z  }| j                  |       d}n|j                  |       t        |t        ||   d               }	|	d|z  }| j                  |       d}g|	|k7  smd||	fz  }| j                  |       d} |r(t        |      D ]  }d	|z  }| j                  |        d}|S )
zBverify that the provided nodemap data are valid for the given idexr   s   revisions in index:   %d
s   revisions in nodemap: %d
s$     revision missing from nodemap: %d
r   r   s/     revision node does not match any entries: %d
s?     revision node does not match the expected revision: %d != %d
s"     extra revisions in  nodemap: %d
)statusr<   r  set_all_revisionsr   	write_errremove
_find_noder   rs   )
uir   rG   retr   r
  all_revsrr   nm_revs
             r   
check_datar*  e  s;   
CII,E
:;$HD">$'(HII,H=>3u: H:Q>CLLCOOAD#eAhqk"23>EICLLCq[!"F,  LLC%( ! 	A81<CLL	 Jr   c              #   h   K   t        |       D ]   }|D ]  }|t        |t              r|  " yw)z%return all revisions stored in a TrieN)r  r   r   )r   r   r  s      r   r!  r!    s?     D!  	AyJq%0G	s   02c                 ~    | j                  t        |dd             }t        |t              rt	        ||dd       S |S )z.find the revision associated with a given noder   r   N)r6   r   r   r   r$  )r   r   r   s      r   r$  r$    s=    IIgd1Qi()E%%ab**Lr   c                     | j                   r,| j                  dz   }| j                  j                  |      r|S | j                  dz   S )Ns   .n.as   .n)_trypendingrx   r(   exists)r=   pending_paths     r   r   r     s@    ||g-==-<<%r   )FFrR   )/ry   structr   r    r   r   r   r	   r   r   r   r   r$   rH   rX   rZ   rv   r   rM   r-   Structr*   r.   r/   r4   r   r   r   r   r  r   r   r   r   r   r   r   r   r  r  r  r  r*  r!  r$  r   r   r   r   <module>r4     s   
   
 #9d 9
	
D(VH( 2!"#o.P FMM$	6=="F FR.
L &--(
)

4D 4D&	$$< F r   