
    q&f                         d Z ddlmZ ddlmZmZ dZedz  ZdZedz  Z	ee	z
  Z
e
dz  Zedz
  dz  Zd	 Zd
ededefdZd Zd Zd Z ed      D  cg c]
  }  e|        c} Zd Zd Zd Zd Z G d d      Zyc c} w )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)pycompatutili              c                 :    d}| D ]  }|dz  t        |      z   } |S )zconvert a bytestring to a long       )ord)bsvbs      0/usr/lib/python3/dist-packages/mercurial/pvec.py_binr   C   s-    	A Gc!fH    r   lreturnc                 j    d}t        |      D ]"  }t        j                  | dz        |z   }| dz  } $ |S )Nr      r   )ranger   bytechr)r   r   r   ps       r   _strr   K   sC    	B1X a#g&+	a Ir   c                 J    t        | dt               t        | t        d       fS )zdepth and bitvecN)r   _depthbytes)r   s    r   _splitr   S   s#    ,; $q"777r   c                 D    t        | t              t        |t              z   S N)r   r   	_vecbytes)depthbitvecs     r   _joinr$   X   s    {#d69&===r   c                 2    d}| r| dz  r|dz  }| dz  } | r|S )Nr   r    )xcs     r   _hweightr)   \   s/    	A
q5FA	a  Hr   r   c                 F    | |z  }d}|r|t         |dz     z  }|dz  }|r|S )z+find the hamming distance between two longsr   r   r   )_htab)ar   dr(   s       r   _hammingr.   h   s:    	AA	A
	U1t8_	a  Hr   c                     | \  }}|\  }}||k  r||||f\  }}}}t        ||      }||z
  }|}	||z  }
d}||kD  r||z
  dz   dz  }nd}||z   }|
r|r|
|z  r
|	|z  }	|dz  }|dz  }|r||	fS t        |	|      }	||	fS )Nr   r	   )r.   _flipbit)r'   yr(   d1v1d2v2hdistddistr   michangesr"   s                 r   	_mergevecr;   r   s    
 FBFB	BwRRBBREGE
A
RA	Au} 5=1$* LE 	1uQ1!GA	  !8O QN!8Or   c                 <    t        |      dz  t        z  }| d|z  z  S )Nl    r   )hash_vecbits)r   nodebits      r   r0   r0      s#    :
"h
.CS>r   c                 `   | j                         }t        |d      si |_        |j                  }| j                         |vr|j                  }t        | j                         dz         D ]  }||vs|j                  |      }|j                  |      \  }}|t        k(  rdt        |dz  dt               f||<   Q|t        k(  r||   \  }}	|dz   t        |	|      f||<   wt        ||   ||   |      ||<    t        || j                             }
t        t        j                   |
            S )z3construct a pvec for ctx while filling in the cache
_pveccacher   r      N)repohasattrrB   rev	changelogr   r?   
parentrevsr   r   r!   r0   r;   r$   pvecr   	b85encode)ctxrpvcclnr?   p1p2r-   r   r   s              r   ctxpvecrR      s   
A1l#
,,C
wwy[[swwy1}% 	?A|wwqzq)B=tax)&<!=>CF7]r7DAq!eXa%67CF&s2wB>CF	? 
CGGI	Br"##r   c                   B    e Zd Zd Zd Zd Zd Zd Zd Zd Z	d Z
d	 Zy
)rI   c                     t        |t              r3|| _        t        t	        j
                  |            \  | _        | _        y t        |      | _        y r    )	
isinstancebytes_bsr   r   	b85decode_depth_vecrR   )self	hashorctxs     r   __init__zpvec.__init__   s;    i' DH%+DNN9,E%F"DK	*DIr   c                     | j                   S r    )rW   )r[   s    r   __str__zpvec.__str__   s    xxr   c                 j    | j                   |j                   k(  xr | j                  |j                  k(  S r    )rZ   rY   r[   r   s     r   __eq__zpvec.__eq__   s'    yyAFF">t{{ahh'>>r   c                     |j                   | j                   z
  }|dk  ryt        | j                  |j                        |kD  ryy)Nr   FT)rY   r.   rZ   r[   r   deltas      r   __lt__zpvec.__lt__   s;    4;;&19DIIqvv&.r   c                     || k  S r    r&   ra   s     r   __gt__zpvec.__gt__   s    4xr   c                     t        |j                  | j                  z
        }t        | j                  |j                        |k  ryy)NFT)absrY   r.   rZ   rd   s      r   __or__zpvec.__or__   s6    AHHt{{*+DIIqvv&%/r   c                 T    | |z  rt        d      | j                  |j                  z
  S )Ns   concurrent pvecs)
ValueErrorrY   ra   s     r   __sub__zpvec.__sub__   s(    !8011{{QXX%%r   c                     t        |j                  | j                  z
        }t        | j                  |j                        }t	        ||      S r    )rj   rY   r.   rZ   max)r[   r   r-   hs       r   distancezpvec.distance   s9    4;;&'TYY'1ayr   c                     t        |j                  | j                  z
        }|t        kD  s't	        | j
                  |j
                        t        kD  ryy )NF)rj   r"   rY   _radiusr.   rZ   )r[   r   dists      r   nearz	pvec.near   s?    177T[[()'>Xdii87B Cr   N)__name__
__module____qualname__r]   r_   rb   rf   rh   rk   rn   rr   rv   r&   r   r   rI   rI      s/    +?&

r   rI   N)__doc__r?   r    r   r   _size_bytes
_depthbitsr   r!   r>   rt   r   intrV   r   r   r$   r)   r   r+   r.   r;   r0   rR   rI   )r'   s   0r   <module>r      s   )X 
 		!
Ao[ 	q=b=Q
C C E 8
> $Cj)!)#L$0, ,c 	*s   A: