o ]LbQV@sddlmZddlZddlZddlZddlmZddlmZm Z m Z ddlm Z Gdd d e Zd d Zd d ZddZddZGdddeZddZddZdGddZdZedZedZGdddeZdd Zd!d"Zd#d$Zd%d&Z ed'Z!d(Z"dZ#d)d*Z$d+d,Z%Gd-d.d.e Z&d/d0Z'd1d2Z(d3d4Z)dHd5d6Z*d7d8Z+d9d:Z,d;d<Z-d=d>Z.d?d@Z/dAdBZ0dCdDZ1dEdFZ2dS)I)absolute_importN)hex)error requirementsutil)docketc@seZdZddZdS)NodeMapcCstd|)Nsunknown node: %s)r RevlogError)selfxr?/usr/lib/python3/dist-packages/mercurial/revlogutils/nodemap.py __missing__zNodeMap.__missing__N)__name__ __module__ __qualname__rrrrrr s r cCsdS)zrhook point for test This let tests to have things happens between the docket reading and the data readingNrrrrrtest_race_hook_1srcCsLtj|jvrdStj|jvrdS|}td||jtd||jjjdS)zoThe stream clone might needs to remove some file if persisten nodemap was dropped while stream cloning N) rREVLOGV1_REQUIREMENTNODEMAP_REQUIREMENT unfiltereddelete_nodemap changelog manifestlog _rootstore_revlog)repounfirrrpost_stream_cleanup&s  r c Cs|jdurdS|j|j}|sdSd}t|||tj\}|tkr'dS|tj7}t|||tj}|\}}}}} |tj7}t||||} ||7}|| _ |||| | _ || _ || _ t || } |jjd} tz5|| &} | rz tt| |}Wntyd}Ynw| |}Wdn1swYWnttfy}z|jtjkrWYd}~dSd}~wwt||krdS| |fS)z'read the nodemap for a revlog from diskNrpersistent-nodemap.mmap) _nodemap_fileopenertryread S_VERSIONunpacksizeONDISK_VERSIONS_HEADER NodeMapDockettip_revtip_node data_length data_unused_rawdata_filepathoptionsgetrrbuffermmapread ValueErrorreadIOErrorOSErrorerrnoENOENTlen)revlogpdataoffsetversionheadersuid_sizer,r.r/ tip_node_sizer filenameuse_mmapfddataerrrpersisted_data3sV         rHcs\jrdSjdur dSdj}||rdS||fdd||fdddS)zInstall whatever is needed transaction side to persist a nodemap on disk (only actually persist the nodemap if this is relevant for this revlog) Nsnm-revlog-persistent-nodemap-%scst|ddS)NT)pendingpersist_nodemaptrr<rrpsz*setup_persistent_nodemap..cs t|SNrJrLrNrrrOrs )_inliner# hasfinalize addpending addfinalize)rMr< callback_idrrNrsetup_persistent_nodemapas    rVc@sHeZdZdZddZddZddZdd Zd d Zd d Z ddZ dS)_NoTransactionzCtransaction like object to update the nodemap outside a transactioncCs i|_dSrP _postcloser rrr__init__xs z_NoTransaction.__init__cCs||j|<dSrPrX)r rU callback_funcrrr addpostclose{rz_NoTransaction.addpostclosecOdSrPrr argskwargsrrr registertmp~z_NoTransaction.registertmpcOr^rPrr_rrr addbackuprcz_NoTransaction.addbackupcOr^rPrr_rrraddrcz_NoTransaction.addcOr^rPrr_rrraddabortrcz_NoTransaction.addabortcGr^rPr)r r`rrr_reportrcz_NoTransaction._reportN) rrr__doc__r[r]rbrdrerfrgrrrrrWus rWcCsJ|jrdS|jdur dSt}t||t|jD] }|j|dqdS)zupdate the persistent nodemap right now To be used for updating the nodemap on disk outside of a normal transaction setup (eg, `debugupdatecache`). N)rQr#rWrKsortedrY)r<notrkrrrupdate_persistent_nodemaps  rlcCsN|j}td|}|j|j}|j|D] }||r$|j |qdS)z.Delete nodemap data on disk for a given revlogs"(^|/)%s(-[0-9a-f]+\.nd|\.n(\.a)?)$N) radixrecompiler$dirname _indexfilelistdirmatchsvfs tryunlink)rMrr<prefixpatterndirpathfrrrrs  rFcs,t|ddr td|jdur|rt||_nd}t|t|jd}|j}t|jd}|j j d}d} |r|dur|j } |j \} } } | jt| } | j| }| | kr_d} nX| |d krhd} nOt|| || j| d /}|| j|| |r|r|d || }n |tt|| }Wdn1swY| | _|| _| dur#t} t|| t|jd r|j} nt|j} |j jfd d}d}|||| d$}|| |r|r| }n|tt|t| }Wdn 1swYt| | _|| _| | j| _!|j}|r?|d7}|"|n|#||j |ddd}|| $Wdn 1s_wY| |_|rq|j%| |t&|| rt|d|j fdd}d|j}|'||dSdS)z-Write nodemap data on disk for a given revlog filteredrevsrz.cannot persist nodemap of a filtered changelogNz?calling persist nodemap on a revlog without the feature enablednodemap_data_incrementalupdate_nodemap_datar! sr+rnodemap_data_allcs dSrPrrL)datafilerurrabortcks z persist_nodemap..abortcks delete-%ssw+s.awT) atomictemp _realopenercsD]}|qdSrP)ru)rMoldfile)oldsrealvfsrrcleanups z persist_nodemap..cleanupsrevlog-cleanup-nodemap-%s)(getattrrProgrammingErrorr#get_nodemap_filer safehasattrindex_nodemap_docketr$r1r2copyr{r.r;r/r0reseekwriter6flushr3r4r+r~persistent_datarurftiprevr,noder-rbrd serializer|_other_rawdata_filepathr])rMr<rIforcemsgcan_incremental ondisk_docket feed_datarDrF target_docket src_docketdata_changed_count new_length new_unusedrEnew_datarrU file_pathfprr)rrrrurrKs                          rKz>Bz>BQQQQc@s:eZdZdZd ddZddZddZd d Zd d ZdS)r+z}metadata associated with persistent nodemap data The persistent data may come from disk or be on their way to disk. NcCs2|durt}||_d|_d|_d|_d|_dS)Nr) docket_modmake_uiduidr,r-r.r/)r rrrrr[:s  zNodeMapDocket.__init__cCs0t|jd}|j|_|j|_|j|_|j|_|S)N)r)r+rr,r-r.r/)r newrrrrVs zNodeMapDocket.copycCsD|j|jkrdS|j|jkrdS|j|jkrdS|j|jkr dSdS)Nrrrr.r otherrrr__cmp__^s    zNodeMapDocket.__cmp__cCs|j|jko |j|jkSrPrrrrr__eq__iszNodeMapDocket.__eq__cCsfg}|ttt|j|j|j|jt|j f}|t j|||j||j d |S)z9return serialized bytes for a docket using the passed uidr") appendr&packr)r;rr,r.r/r-r*join)r rFr@rrrrls   zNodeMapDocket.serializerP) rrrrhr[rrrrrrrrr+4s  r+cCs|j}d||jfS)z9The (vfs relative) nodemap's rawdata file for a given uids%s-%s.nd)rmr)r<r rvrrrr0}sr0c Csl|j}td|}t||}|j|}|j|}g}|j|D]}||r3||kr3| |q#|S)Ns(^|/)%s-[0-9a-f]+\.nd$) rmrnror0r$basenamerprrrsr) r<r rvrw new_file_path new_file_namerxothersryrrrrs    rcCst|}t|S)zAreturn the persistent binary form for a nodemap for a given index) _build_trie _persist_trie)rtrierrrrsrcCs&t|||\}}|tjt||dfS)zGreturn the incremental update for persistent nodemap from a given index) existing_idx) _update_trieS_BLOCKr(r)rrootmax_idxlast_rev changed_blockrrrrupdate_persistent_datas rz>llllllllllllllllrcCs |t 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)revrrr_transform_revs rcCs t|dS)z/turn an hexadecimal digit into a proper integer)int) hex_digitrrr_to_ints rcs(eZdZdZfddZddZZS)BlockzOrepresent a block of the Trie contains up to 16 entry indexed from 0 to 15cstt|d|_dSrP)superrr[ ondisk_idrZ __class__rrr[s zBlock.__init__cstfddtdDS)Nc3s|]}|VqdSrP)r2).0irZrr z!Block.__iter__..r)iterrangerZrrZr__iter__szBlock.__iter__)rrrrhr[r __classcell__rrrrrs rcCs<t}tt|D]}t||d}t|d|||q |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)rrr;r_insert_into_block)rrr current_hexrrrrs rcCsHd}t|dt|D]}t||d}|t|d|||7}q ||fS)consumerrr)rr;rr)rrrchangedrrrrrrs rc Csd}|jdur d|_t|||d}||}|dur#|||<|St|tr6|t||d|||7}|St||d}|} t} | ||<t||d| | |t||d| |||S)a7insert 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 rNr)rrr2 isinstancedictrrr) rlevelblock current_revrrrentry other_hex other_revrrrrrs(    rcCsti}|dur |d}nd}g}t|D]!}|jdur"|j|t|<qt|||t|<|t||qd|S)zaturn a nodemap trie into persistent binary data See `_build_trie` for nodemap trie structureNrrr") _walk_trieridr;r_persist_blockr)rr block_mapbase_idxchunkstnrrrrs    rccs@t|D]\}}t|trt|D]}|Vqq|VdS)zcyield all the block in a trie Children blocks are always yield before their parent block. N)riitemsrrr)r__item sub_blockrrrr*s   rcs tfdd|D}tj|S)zproduce persistent binary data for a single block Children block are assumed to be already persisted and present in block_map. c3s|]}t|VqdSrP) _to_value)rvrrrr<rz!_persist_block..)tuplerr) block_noderrFrrrr6s rcCs*|durtSt|tr|t|St|S)zpersist any value as an integerN)NO_ENTRYrrrr)rrrrrr@s   rc Cst|tjdkrd}t|tjt|f|stdfSi}g}tdt|tjD]$}t}t||_|||j<|||tj}t|}| ||fq+|D]#\}}t |D]\} } | t krcqZ| dkrn|| || <qZt | || <qZqR||tjfS)z,parse parse nodemap data into a nodemap Triers:nodemap data size is not a multiple of block size (%d): %dN) r;rr(rAbortrrrr'r enumeraterr) rFrr new_blocksrr block_datavaluesbidxrrrr parse_dataJs.     rc Csd}|dt|t|\}}tt|}|dt|tt|D]C}||vr8d|}||d}n||t|t ||d} | durXd|}||d}q&| |krid || f}||d}q&|r~t |D] }d |}||qpd}|S) zBverify that the provided nodemap data are valid for the given idexrsrevision in index: %d srevision in nodemap: %d s$ revision missing from nodemap: %d rrNs/ 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;rset_all_revisionsr write_errremove _find_noderri) uirrFretrrall_revsrrnm_revrrr check_datahs<        rccs8t|D]}|D]}|dust|trq |Vq qdS)z%return all revisions stored in a TrieN)rrr)rrrrrrrs rcCs6|t|dd}t|trt||ddS|S)z.find the revision associated with a given noderrN)r2rrrr)rrrrrrrs rcCs*|jr|jd}|j|r|S|jdS)Ns.n.as.n) _trypendingrmr$exists)r< pending_pathrrrrs    r)FFrP)3 __future__rr9rnstructrrrrrr rrr rr rHrVobjectrWrlrrKr)Structr&r*r+r0rrrrrrrrrrrrrrrrrrrrrrrrrsV    .   I&   "   #