^cdZddlmZddlmZmZdZedzZdZedzZ ee z Z e dzZ e dz dzZ d Z d Zd Zd Zd ZdedDZdZdZdZdZGddZdS)a3 A "pvec" is a changeset property based on the theory of vector clocks that can be compared to discover relatedness without consulting a graph. This can be useful for tasks like determining how a disconnected patch relates to a repository. Currently a pvec consist of 448 bits, of which 24 are 'depth' and the remainder are a bit vector. It is represented as a 70-character base85 string. Construction: - a root changeset has a depth of 0 and a bit vector based on its hash - a normal commit has a changeset where depth is increased by one and one bit vector bit is flipped based on its hash - a merge changeset pvec is constructed by copying changes from one pvec into the other to balance its depth Properties: - for linear changes, difference in depth is always <= hamming distance - otherwise, changes are probably divergent - when hamming distance is < 200, we can reliably detect when pvecs are near Issues: - hamming distance ceases to work over distances of ~ 200 - detecting divergence is less accurate when the common ancestor is very close to either revision or total distance is high - this could probably be improved by modeling the relation between delta and hdist Uses: - a patch pvec can be used to locate the nearest available common ancestor for resolving conflicts - ordering of patches can be established without a DAG - two head pvecs can be compared to determine whether push/pull/merge is needed and approximately how many changesets are involved - can be used to find a heuristic divergence measure between changesets on different branches )nullrev)pycompatutilic>d}|D]}|dzt|z}|S)zconvert a bytestring to a long)ord)bsvbs 0/usr/lib/python3/dist-packages/mercurial/pvec.py_binrCs1 A  Gc!ff  Hcld}t|D]!}tj|dz|z}|dz}"|S)Nrr)rangerbytechr)rlrps r_strrKsE B 1XX  a#g & & + a Ircrt|dtt|tdfS)zdepth and bitvecN)r _depthbytes)rs r_splitrTs- ,;, $q"7"7 77rcXt|tt|tzSN)rr _vecbytes)depthbitvecs r_joinr#Ys! { # #d69&=&= ==rc0d}|r|dzr|dz }|dz}||S)Nr r)xcs r_hweightr(]s> A  q5  FA a  Hrc,g|]}t|Sr%)r().0r&s r r+fs)))!)))rr cL||z }d}|r|t|dzz }|dz}||S)z+find the hamming distance between two longsr rr)_htab)ardr's r_hammingr0isD AA A  U1t8_ a  Hrc|\}}|\}}||kr ||||f\}}}}t||}||z }|} ||z } d} ||kr ||z dzdz} nd} || z} | r| r| | zr | | z} | dz} | dz} | nt| |} | | fS)Nrr )r0_flipbit)r&yr'd1v1d2v2hdistddistrmichangesr!s r _mergevecr=ss FB FB BwwRRBB R  E GE A RA A u}}5=1$* LE  1u Q1  !GA   QNN !8OrcFt|dztz}|d|zz S)Nlr)hash_vecbits)rnodebits rr2r2s% :: "h .C S>rc|}tj|dsi|_|j}||vr|j}t |dzD]}||vr||}||\}}|tkr%dt|dzdtf||<c|tkr$||\}} |dzt| |f||<t|||||||<t||} ttj| S)z3construct a pvec for ctx while filling in the cache _pveccacherr N)repor safehasattrrDrev changelogrrA parentrevsrrr r2r=r#pvec b85encode) ctxrpvcclnrAp1p2r/rrs rctxpvecrTsJ  A  A| , , ,C wwyy [swwyy1}%% ? ?A||wwqzzq))B==tax)&CFF7]]r7DAq!eXa%6%67CFF&s2wB>>CF CGGII B r"" # ##rcDeZdZdZdZdZdZdZdZdZ dZ d Z d S) rKct|tr7||_tt j|\|_|_dSt||_dSr) isinstancebytes_bsrr b85decode_depth_vecrT)self hashorctxs r__init__z pvec.__init__sR i ' ' + DH%+DN9,E,E%F%F "DK **DIIIrc|jSr)rY)r]s r__str__z pvec.__str__s xrcB|j|jko|j|jkSr)r\r[r]rs r__eq__z pvec.__eq__syAF">t{ah'>>rct|j|jz }|dkrdSt|j|j|krdSdS)Nr FT)r[r0r\r]rdeltas r__lt__z pvec.__lt__sA4;& 1995 DIqv & & . .5trc||kSrr%rcs r__gt__z pvec.__gt__s 4xrc~t|j|jz }t|j|j|krdSdS)NFT)absr[r0r\rfs r__or__z pvec.__or__s;AHt{*++ DIqv & &% / /5trcH||zrtd|j|jz S)Nsconcurrent pvecs) ValueErrorr[rcs r__sub__z pvec.__sub__s, !8 2011 1{QX%%rct|j|jz }t|j|j}t ||Sr)rlr[r0r\max)r]rr/hs rdistancez pvec.distances9 4;& ' ' TY ' '1ayyrct|j|jz }|tks#t |j|jtkrdSdS)NF)rlr!r[_radiusr0r\)r]rdists rnearz pvec.nearsG17T[()) '>>Xdi887BB5CBrN) __name__ __module__ __qualname__r_rardrhrjrmrprtrxr%rrrKrKs+++??? &&&  rrKN)__doc__rArrr_size_bytes _depthbitsrr r@rvrrrr#r(rr-r0r=r2rTrKr%rrrsb))X  !  Ao [ q= b=Q    888 >>>    *)eeCjj)))   ###L $$$0,,,,,,,,,,r