
    	^cU                        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.dS )/    N   )hex)errorrequirementsutil   )docketc                       e Zd Zd ZdS )NodeMapc                 0    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8    N)__name__
__module____qualname__r    r   r   r   r      s#        9 9 9 9 9r   r   c                      dS )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	    
 	Dr   c                     t           j        | j         vrdS t           j        | j         v rdS |                                 }t	          d||j                   t	          d| |j        j        j                   dS )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$   $   st     (0AAA'4+<<<??D4t~...4t/:BCCCCCr   c                    | j         dS | j                            | j                   }|sdS d}t                              |||t          j        z                      \  }|t          k    rdS |t          j        z  }t                              |||t          j        z                      }|\  }}}}}	|t          j        z  }t          ||||z                      }
||z  }||
_	        ||||	z            |
_
        ||
_        ||
_        t          | |
          }| j        j                            d          }t!                       	 |                     |          5 }|r;	 t#          j        t#          j        ||                    }n'# t(          $ r d}Y nw xY w|                    |          }ddd           n# 1 swxY w Y   n# t,          $ r Y dS w xY wt/          |          |k     rdS |
|fS )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   sP   #tM!!&"677E tF!!%).1H(H"IJJJW.  t
inFooeFVhm-C$CDEEGAH>Hg{K
hmF5&8*;!;<==F
hFFNFVm%;;<FO$F$F 00H}$(()CDDH]]8$$ 	, ,;t}R'E'EFFDD!   DDD ww{++	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	,    tt
4yy;t4<sZ   G F:'FF:FF:FF:.G :F>>G F>G 
GGc                     j         rdS j        dS dj        z  }|                     |          rdS |                     |fd           |                     |fd           dS )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 I I r   c                 $    t          |           S NrL   rN   s    r   rP   z*setup_persistent_nodemap.<locals>.<lambda>m   s    ?2v+F+F r   )_inliner'   hasfinalize
addpendingaddfinalize)rO   r=   callback_ids    ` r   setup_persistent_nodemaprX   \   s    
 ~ # 5v7KKK	~~k"" MMIIII   NN; F F F FGGGGGr   c                   <    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	S )
_NoTransactionzCtransaction like object to update the nodemap outside a transactionc                     i | _         d S rR   
_postcloser   s    r   __init__z_NoTransaction.__init__s   s    r   c                     || j         |<   d S rR   r\   )r   rW   callback_funcs      r   addpostclosez_NoTransaction.addpostclosev   s    '4$$$r   c                     d S rR   r   r   argskwargss      r   registertmpz_NoTransaction.registertmpy       r   c                     d S rR   r   rd   s      r   	addbackupz_NoTransaction.addbackup|   rh   r   c                     d S rR   r   rd   s      r   addz_NoTransaction.add   rh   r   c                     d S rR   r   rd   s      r   addabortz_NoTransaction.addabort   rh   r   c                     d S 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M  5 5 5            r   rZ   c                     | j         rdS | j        dS t                      }t          ||            t	          |j                  D ]} |j        |         d           dS )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      sy     ~ #DD&!!!DO$$ ! !4    ! !r   c                    |j         }t          j        d|z            }|j                            |j                  }|j                            |          D ]1}|                    |          r|j        	                    |           2dS )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      s    \Fj?&HIIGm##F$566G]""7++ # #== 	#I"""# #r   Fc           	      P	   t          |dd          rt          j        d          |j        -|rt	          |          |_        nd}t          j        |          t          j        |j        d          }|j        }t          j        |j        d          }|j	        j
                            d          }d}	|rq|n|j                                        }
|j                                        \  }}}	|
j        t          |	          z   }|
j        |z   }||
k    rd}	n||d	z  k    rd}	n t#          ||
          |                     |
j                   |	                    d
          5 }|                    |
j                   |                    |	           |rh|r+|                    d           |                    |          }n;|                                 t          j        t          j        ||                    }ddd           n# 1 swxY w Y   ||
_        ||
_        |	9t3                      }
t#          ||
          t          j        |j        d          r|j                                        }	nt7          |j                  }	|j	        j        fd}dz  }|                     ||           |	                    d          5 }|                    |	           |rM|r|	}nH|                                 t          j        t          j        |t          |	                              }ddd           n# 1 swxY w Y   t          |	          |
_        |                                |
_        |                     |
j                  |
_!        |j        }|r|dz  }| "                    |           n| #                    |           |	                    |dd          5 }|                    |
$                                           ddd           n# 1 swxY w Y   |
|_        |r|j        %                    |
|           tM          ||
          r>t          |d|j	                  fd}d|j        z  }| '                    ||           dS dS )z-Write nodemap data on disk for a given revlogfilteredrevsr   z.cannot persist nodemap of a filtered changelogNz?calling persist nodemap on a revlog without the feature enablednodemap_data_incrementalupdate_nodemap_datar&   
   s   r+r   nodemap_data_allc                                 d S rR   r   )rO   datafiler   s    r   abortckz persist_nodemap.<locals>.abortck   s    Ihr   s	   delete-%ss   w+s   .a   wT)
atomictemp_realopenerc                 <    D ]}                     |           d S rR   )r   )rO   oldfileoldsrealvfss     r   cleanupz persist_nodemap.<locals>.cleanup  s3     + +!!'****+ +r   s   revlog-cleanup-nodemap-%s)(getattrr   ProgrammingErrorr'   get_nodemap_filer   safehasattrindex_nodemap_docketr(   r5   r6   copyr   r2   r<   r3   r4   rl   seekwriter:   flushr7   r8   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   v~r** 
$<
 
 	
 # 	.#3F#;#;F  SC(---&v|5OPPO*M /DEEI}$(()CDDHD 3=4.3355
 L1133		
".T:
".1CC
&&DDJO,,DD(??H FF8]6777x// 	N21222 N N


#%77:#6#6


#';t}R/L/L#M#M	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N )3M%(2M%|%$V];;FL*<== 	1<0022DD"6<00D M+		  	  	  	  	  	  #X- 	K)))]]8U++ 	IrHHTNNN I I#HHHHJJJ#{4=SYY+G+GHHH	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I %(II!"MMOOM#[[)>??M $I  U	
y!!!!
Y	y$4	8	8 ,B
((**+++, , , , , , , , , , , , , , ,*F B((AAA #6=99D .&-??	+ 	+ 	+ 	+ 	+ 	+ 3V5II
W-----. .s8   /BHHHA%MMM3(P''P+.P+z>Bz>BQQQQc                   2    e Zd ZdZddZd Zd Zd Zd ZdS )	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| _        d S )Nr   )
docket_modmake_uiduidr0   r1   r2   r3   )r   r   s     r   r_   zNodeMapDocket.__init__5  sJ    ;%''C   
   r   c                     t          | j                  }| j        |_        | j        |_        | j        |_        | j        |_        |S )N)r   )r/   r   r0   r1   r2   r3   )r   news     r   r   zNodeMapDocket.copyQ  s?    )))l}**
r   c                     | j         |j         k     rdS | j         |j         k    rdS | j        |j        k     rdS | j        |j        k    rdS dS )Nr   r   r   r2   r   others     r   __cmp__zNodeMapDocket.__cmp__Y  s[    8ei28ei1 1112 1111qr   c                 B    | j         |j         k    o| j        |j        k    S rR   r   r   s     r   __eq__zNodeMapDocket.__eq__d  s!    x59$N)9U=N)NNr   c                    g }|                     t                              t                               t	          | j                  | j        | j        | j        t	          | j	                  f}|                     t          j        |            |                     | j                   |                     | j	                   d                    |          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.serializeg  s    INN>22333MML
 	HM7+,,,DHDM"""xx~~r   rR   )	r   r   r   rq   r_   r   r   r   r   r   r   r   r/   r/   /  sq         
   8  	 	 	O O 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   x  s    \F&&*---r   c                 h   | j         }t          j        d|z            }t          | |          }| j                            |          }| j                            |          }g }| j                            |          D ]2}|                    |          r||k    r|	                    |           3|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j3f<==G%ff55MM**=99Mm##M22GF]""7++  == 	] 2 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                 j    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     s<    &udH==M4$d11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                 d    t          t          |                                            d | _        d S rR   )superr   r_   	ondisk_id)r   	__class__s    r   r_   zBlock.__init__  s*    eT##%%%r   c                 T     t           fdt          d          D                       S )Nc              3   B   K   | ]}                     |          V  d S rR   )r6   ).0ir   s     r   	<genexpr>z!Block.__iter__.<locals>.<genexpr>  s-      33ADHHQKK333333r   r   )iterranger^   s   `r   __iter__zBlock.__iter__  s,    3333r333333r   )r   r   r   rq   r_   r   __classcell__)r   s   @r   r   r     sQ        4 4    
4 4 4 4 4 4 4r   r   c                     t                      }t          t          |                     D ]0}t          | |         d                   }t	          | d|||           1|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     s]     77DSZZ   = =%*Q-((5!T3<<<<Kr   c           	          d}t          |dz   t          |                     D ]3}t          | |         d                   }|t          | d|||          z  }4||fS )consumer   r   r   )r   r<   r   r   )r   r   r   changedr   r   s         r   r   r     sh    GX\3u::.. H H%*Q-((%eQc;GGGD=r   c                    d}|j         d|_         t          |||dz                      }|                    |          }||||<   nt          |t                    r|t          | |dz   |||          z  }n\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$5677IIIi  E}&i	E4	 	  L%519e[+
 
 	
 eQ((		ggi5%!)S)YGGG5%!)S+{KKKNr   c                 4   i }||dz   }nd}g }t          |           D ]f}|j        |j        |t          |          <   !t          |          |z   |t          |          <   |                    t          ||                     gd                    |          S )zaturn a nodemap trie into persistent binary data

    See `_build_trie` for nodemap trie structureNr   r   r   )
_walk_trier   idr<   r   _persist_blockr   )r   r   	block_mapbase_idxchunkstns         r   r   r     s     I!#F 9 9<# "Ibff #Fh 6IbffMM.Y77888888Fr   c              #      K   t          |                                           D ]0\  }}t          |t                    rt	          |          D ]}|V  1| V  dS )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  %  sm      
 U[[]]++    
TdD!! 	 '--    	
KKKKKr   c                 V    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   8   K   | ]}t          |          V  d S rR   )	_to_value)r   vr  s     r   r   z!_persist_block.<locals>.<genexpr>7  s-      ==Q1i((======r   )tupler   r   )
block_noder  rG   s    ` r   r  r  1  s4     ====*=====D<r   c                     | 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  ;  s=    |	D$		 $D""d###r   c                    t          |           t          j        z  dk    r2d}t          j        |t          j        t          |           fz            | st                      dfS i }g }t          dt          |           t          j                  D ]v}t                      }t          |          |_        |||j        <   | ||t          j        z            }t                              |          }|	                    ||f           w|D ]J\  }}t          |          D ]5\  }	}
|
t          k    r|
dk    r||
         ||	<   #t          |
          ||	<   6K||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  E  sf   D		GL Q&&Kk#s4yy 99::: ww}IJ1c$ii.. + +i..%*	%/"!a',../

++5&/**** + +	6'' 	+ 	+FCH}}a"1#'**#	+ !w|###r   c                    d}|                      dt          |          z             t          |          \  }}t          t	          |                    }|                      dt          |          z             t          t          |                    D ]}||vrd|z  }|                     |           d}n|                    |           t          |t          ||         d                             }	|	d|z  }|                     |           d}|	|k    rd	||	fz  }|                     |           d}|r.t          |          D ]}d
|z  }|                     |           d}|S )zBverify that the provided nodemap data are valid for the given idexr   s   revision in index:   %d
s   revision in nodemap: %d
s$     revision missing from nodemap: %d
r   r   Ns/     revision node does not match any entries: %d
s?     revision node does not match the expected revision: %d != %d
s!     extra revision 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*  c  s   
CII+s5zz9:::$HD">$''((HII+s8}}<===3u::  H:Q>CLLCCOOAD#eAhqk"2"233>EICLLCCq[[!"F,  LLC !! 	 	A7!;CLLJr   c              #   p   K   t          |           D ]#}|D ]}|t          |t                    r|V  $dS )z%return all revisions stored in a TrieN)r  r   r   )r   r   r  s      r   r!  r!    s\      D!!   	 	AyJq%00yGGGG	 r   c                     |                      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$    sR    IIgd1Q3i(())E% +%abb***Lr   c                 p    | j         r&| j        dz   }| j                            |          r|S | j        dz   S )Ns   .n.as   .n)_trypendingrx   r(   exists)r=   pending_paths     r   r   r     sD      |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   
			                
 # " " " " "9 9 9 9 9d 9 9 9
	 	 	
D 
D 
D( ( (VH H H(       2! ! !"# # #m. m. m. m.L FM$	6=""F F F F F F F FR. . .
 
 
L     &-(
)
)
    
4 4 4 4 4D 4 4 4      D   &	 	 	  $ $ $$ $ $<     F             r   