o ]LbR~ @sVddlmZddlZddlmZmZmZddlmZm Z m Z m Z m Z m Z ddlmZmZe jr[ddlmZmZmZmZmZmZmZmZmZddlmZeeeeeeeeeeef s[JejZejZej Z ej!Z!Gd d d e"Z#d d Z$d dZ%Gddde"Z&Gddde&Z'dZ(de(Z)de(Z*dZ+ee+Z,de,Z-dZ.dZ/dZ0Gddde"Z1dS))absolute_importN)binhexnullrev)encodingerrorobsoletepycompatscmutilutil) repoviewutil stringutil) AnyCallableDictIterableListOptionalSetTupleUnion) localrepoc@s@eZdZdZddZddZddZdd Zd d Zd d Z dS)BranchMapCachez8mapping of filtered views of repo with their branchcachecCs i|_dSN) _per_filterselfr5/usr/lib/python3/dist-packages/mercurial/branchmap.py__init__E zBranchMapCache.__init__cCs|||j|jSr) updatecacher filternamerreporrr __getitem__Hs  zBranchMapCache.__getitem__cs|j}|j}|j|dus|st|g}durLt|}|durH||}|| |jj |j }| fdd|Dnt|| |j j dd|r`|||siJ||j|j<dS)zcz-BranchMapCache.updatecache..r)start) changelogr#rgetvalidfor branchcachefromfile subsettablefilteredcopy filteredrevsextendrevsr'update)rr%clr#r9 subsetnamesubset extrarevsrr*rr"Ls&      zBranchMapCache.updatecachecs|j}|j|j}g}t}t|D]}||7}|D]}|} || \} } | r.||qq|rftfdd|D} t||||  | |d} dD]}| |}| |re| |j |<| |dSqLdSdS)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. c3s|] }t|VqdSr)intr(nodeclrevrrr,sz)BranchMapCache.replace..) closednodes)sbases immutablesservedN)r/rev branchinfosetr itervaluesaddmaxr2rAr5r1rwrite)rr%remotebranchmapr; clbranchinforbheadsclosedbheadshr)bcrtiprevcache candidaterviewrrBrreplaceos@        zBranchMapCache.replacecCs|jdSr)rclearrrrrrYzBranchMapCache.clearcCs:|}|jD]\}}|jr||}||q dSr) unfilteredritems_delayedr5rK)rr%unfir#rUrrr write_delayeds  zBranchMapCache.write_delayedN) __name__ __module__ __qualname____doc__r r&r"rXrYr_rrrrrBs#' rcCstdtt|)zEraises ValueError when branchcache found a node which does not existsznode %s does not exist) ValueErrorr sysstrrrArrr _unknownnodesrgcCs|jdur d|jSdS)Nsbranch cache (%s)s branch cacher#)r%rrr_branchcachedescs  ric@seZdZdZddedddfddZddZdd Zd d Zd d Z ddZ ddZ ddZ ddZ e ZddZeddZddZeddZddZd d!Zd"d#Zd$d%Zd3d'd(Zd)d*Zd+d,Zd-d.Zd/d0Zd1d2ZdS)4r2a<A 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. The cache is serialized on disk in the following format: [optional filtered repo hex hash] ... 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. rNcCs||_d|_|dur|j|_n||_||_||_|dur!t|_n||_t||_ d|_ t|_ ||_ |j dur?dd|_ dSdS)zhasnode 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 changelogFNcSsdS)NTr)xrrrsz&branchcache.__init__..) _repor]nullidtipnoder' filteredhashrG _closednodesdict_entries_closedverified_verifiedbranches_hasnode)rr%entriesrnr'rorDhasnoderrrr s"    zbranchcache.__init__cCs2|jrdS|jD] }||st|qd|_dS)zverify the closed nodes we haveNT)rsrprurg)rrArrr _verifycloseds   zbranchcache._verifyclosedcCsJ||jvs ||jvr dS|j|D] }||st|q|j|dS)z'verify head nodes for the given branch.N)rrrtrurgrI)rbranchnrrr _verifybranchs zbranchcache._verifybranchcCs,t|j|j}|D]}||q dS)z"verifies nodes of all the branchesN)rGrrkeysrtr{)rneedverificationrRrrr _verifyalls zbranchcache._verifyallcCs t|jSr)iterrrrrrr__iter__r!zbranchcache.__iter__cCs||j|<dSr)rr)rkeyvaluerrr __setitem__rZzbranchcache.__setitem__cCs|||j|Srr{rrrrrrrr&   zbranchcache.__getitem__cC||||jvSrrrrrr __contains__ rzbranchcache.__contains__ccs0t|jD]\}}||||fVqdSr)r iteritemsrrr{)rkvrrrrs   zbranchcache.iteritemscCr)z2checks whether a branch of this name exists or notr)rlabelrrr hasbranchs  zbranchcache.hasbranchc CsLd}zzT|||}t|}t|ddd}|dd\}}t|t|}}d}|jj }t |dkr>t|d}||||||d} | |sPt d| ||Wn=ttfylYW|rj|dSdSty} z|jjrd} |j| t|t| fd} WYd} ~ nd} ~ wwW|r|| S|r|ww)N  )rnr'rorwz tip differssinvalid %s: %s )cachevfs _filenamernextrstripsplitrr?r/rwlenr1rdloadIOErrorOSErrorclose Exceptionui debugflagdebugrir forcebytestr) clsr%flineitercachekeylastlrevrorwr+instmsgrrrr3s\      zbranchcache.fromfilecCs~|D]:}|d}|s q|dd\}}}|dvrtdt|}t|}|j|g ||dkr<|j |qdS)z[fully loads the branchcache by reading from the file using the line iterator passedrrrsoczinvalid branch statecN) rrrdrtolocalstriprrr setdefaultappendrprI)rr%rlinerAstaterrrrrJs  zbranchcache.loadcCsd}|jr d||jf}|S)z7name of a branchcache file for a given repo or repoviewsbranch2s%s-%srh)r%filenamerrrrZszbranchcache._filenamecCsRz |j|j}Wn tyYdSw|j|krdStj||jdd}|j|kS)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.FT needobsolete)r/rAr' IndexErrorrnr ro)rr%rAtiphashrrrr1bs   zbranchcache.validforcCs>|d}d}t|D]}||jvr|}d}||fSq ||fS)zhReturn tuple with last open head in heads and false, otherwise return last closed head and true.TF)reversedrp)rheadstiprOrQrrr _branchtipws  zbranchcache._branchtipcCs|||dS)zReturn the tipmost open head on branch head, otherwise return the tipmost closed head on branch. Raise KeyError for unknown branch.r)r)rryrrr branchtipszbranchcache.branchtipcsfdd|DS)Nc3s|] }|jvr|VqdSr)rp)r(rzrrrr,r-z'branchcache.iteropen..r)rnodesrrriteropenszbranchcache.iteropenFcCs*|||j|}|st||}|Sr)r{rrlistr)rryrOrrrr branchheadss  zbranchcache.branchheadsccs.t|D]\}}||f||VqdSr)r rr)rbnrrrr iterbranchesszbranchcache.iterbranchescCs|t|jS)zreturns all the heads)r~r rHrrrrrr iterheadss zbranchcache.iterheadscCs"t||j|j|j|j|j|jS)z-return an deep copy of the branchcache object)typerlrrrnr'rorprrrrr6szbranchcache.copyc CsT|}t|ddsd|_dSzx|j||ddd}t|jd|jg}|jdur2| t|j| d |dd}t t |jD](\}}t|}|D]}|d 7}||jvr_d } nd } | d t|| |fqQqF||jd dt|t|j|d|_WdStttjfy} z|jdt| WYd} ~ dSd} ~ ww)N finalizedTw) atomictemps%drrrrros %s %s %s branchcaches%wrote %s with %d labels and %d nodes Fs couldn't write branch cache: %s )currenttransactiongetattrr]rrrrnr'rorrKjoinsortedr rrrr fromlocalrprrlogrirrrrAbortrrr) rr%trrr nodecountrrrArrrrrrKsJ     zbranchcache.writecst}|ji}|j}|D]}||\}}||g||r,|j |q|j } d} | jj } t |d} t|D]\}} |j|g}fdd|D}t}t| D]j}|| vreq^|sm||q^dd| |D}t}t}t}|D]#}|| vr||q||vs||d|kr||q||qt|t|krdksn||||||||q^|r| durt} || rt|}|t|krt||}||8}|rfd dt|D||<t| }|| kr |} qC| |j kr| |_ | |_||sM|j|_t|_ | D]"}|s1q*tfd d |D}||j krK ||_||_ q*t!j"||j d d |_"t|}|j#$ddt%|||&|dS)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. Nsobsoletecsh|]}|qSrrEr@r;rr z%branchcache.update..cSsg|]}|tkr|qSr)r)r(prrr sz&branchcache.update..rrcsg|]}|qSrrf)r(rErrrr>rc3s|]}|VqdSrrr@rrrr,Ssz%branchcache.update..Trrsupdated %s in %.4f seconds )'r timerr/revbranchcacherFrrrprIrAr'r[ parentrevsr getrevsr rrrr0rGrrr:difference_updateheadrevsminrJ ancestorsrnr1rmrrr rorrrirK)rr%revgen starttime newbranches getbranchinfor)ry closesbranchntiprev topoheadsrobsrevs newheadrevsrPbheadset uncertainnewrevparents samebranch otherbranch obsparentsrfloorrevrr'rdurationrrrr:s    $                   zbranchcache.update)F)r`rarbrcrr rxr{r~rrr&rrr\r classmethodr3r staticmethodrr1rrrrrrr6rKr:rrrrr2sD &   ,    (r2c@seZdZdZddZdS)remotebranchcachez@Branchmap info for a remote connection, should not write locallycCsdSrrr$rrrrKiszremotebranchcache.writeN)r`rarbrcrKrrrrrfs rs-v1s rbc-namessrbc-revss>4sI@ilc@sjeZdZdZdddZddZejddZd d Z d d Z d dZ ddZ dddZ ddZddZdS)raPersistent cache, mapping from revision number to branch name and close. This is a low level cache, independent of filtering. Branch names are stored in rbc-names in internal encoding separated by 0. rbc-names is append-only, and each branch name is only stored once and will thus have a unique index. The branch info for each revision is stored in rbc-revs as constant size records. The whole file is read into memory, but it is only 'parsed' on demand. The file is usually append-only but will be truncated if repo modification is detected. The record for each revision contains the first 4 bytes of the corresponding node hash, and the record is only used if it still matches. Even a completely trashed rbc-revs fill thus still give the right result while converging towards full recovery ... assuming no incorrectly matching node hashes. The record also contains 4 bytes where 31 bits contains the index of the branch and the last bit indicate that it is a branch close commit. The usage pattern for rbc-revs is thus somewhat similar to 00changelog.i and will grow with it but be 1/8th of its size. Tc Cs |jdusJ||_g|_t|_d|_z|jt}t ||_|r-dd| dD|_Wnt t fy?|r=|j |_Ynw|jrrz|jt}||jdd<Wnt t fyq}z|jdt|WYd}~nd}~wwtt |jtt |j|_|jdkrg|_t |j|_dS)NrcSsg|]}t|qSr)rr)r(rrrrrs z+revbranchcache.__init__..s(couldn't read revision branch cache: %s )r#rl_names bytearray_rbcrevs _rbcsnameslenrread _rbcnamesrrrr _branchinforFrrrrr _rbcrecsizer/ _rbcrevslen_rbcnamescount)rr%readonlybndatadatarrrrr sH    zrevbranchcache.__init__cCsFd|_|jdd=d|_t|jj|_t|jt|_ t |ddS)Nrs _namesreverse) rrrrrlr/rrrrr clearcachedpropertyrrrr_clears  zrevbranchcache._clearcCsddt|jDS)NcSsi|]\}}||qSrr)r(r)rRrrr rz0revbranchcache._namesreverse..) enumeraterrrrr _namesreverseszrevbranchcache._namesreversec Cs |jj}|t}|tkr||St|j|tkr||S||dt }t t t |j|\}}t|t@}|r@|tM}|dkrEn;||krfz|j||fWStye|jjd|Ynw|jjd||t}|j|d=t|j||_||S)zWReturn branch name and close flag for rev, using and updating persistent cache.NssRreferenced branch names not found - rebuilding revision branch cache from scratch sPhistory modification detected - truncating revision branch cache to revision %d )rlr/rrrFrrrrA _rbcnodelen unpack_from _rbcrecfmtr bufferbool _rbccloseflag_rbcbranchidxmaskrrrrrrr) rrEr/ rbcrevidxreponode cachenode branchidxrtruncaterrrrFsB        zrevbranchcache.branchinfocCsx|jj}||\}}||jvr|j|}nt|j}|j|||j|<||}|r1|tO}| |||||fS)z7Retrieve branch info from changelog and update _rbcrevs) rlr/rFrrrrrAr  _setcachedata)rrEr/rRrrrrrrrs      zrevbranchcache._branchinfocCs||j\}}||jvr|j|}nt|j}|j|||j|<|r&|tO}|||jj ||dt |vr<|`dSdS)z%add new data information to the cacherFN) rFrrrrr rrlr/rAvars)rrEchangelogrevisionryrrrrrsetdatas       zrevbranchcache.setdatacCs|tkrdS|t}|t}t|j}||kr"|jdtt|tt|j|||t |j ||_ |j }|rB| d|jdSdS)z:Writes the node's branch data to the in-memory cache data.Nrswrite-revbranchcache)rrrrr8rJ _rbcmininc pack_intor rrrlr addfinalizerK)rrErArr requiredsizerbccurrrrrrs  zrevbranchcache._setcachedataNc Cs|j}d}d}zhz5|jt|jkr|jdd}d}|||jt}|t|jkr.N)rropenrtellrrKrrrr unlinkpathrrrr)rr%rrrrr Is&     zrevbranchcache._writenamescCstt|jt|jt}|jtd<}||kr;|j dt|f| |||kr7d}| || |t}| |j||Wdn1sSwY||_ dS)z$write the new revs to revbranchcacher%struncating cache/%s to %d rN)rrr/rrrr'r(rrseekrrKr)rr%r.r9rendrrrr!bs      zrevbranchcache._writerevs)Tr)r`rarbrcr rr propertycacherrFrrrrKr r!rrrrr{s $ /  r)2 __future__rstructrArrrrrr r r r utilsr r TYPE_CHECKINGtypingrrrrrrrrrranyr4calcsizerr objectrrgrir2r _rbcversionrrr rrrrr rrrrrsV  , _<