o ]Lb"@sddlmZddlZddlZddlZddlZddlmZddlm Z ddl m Z m Z ddlm Z dZdZd ZGd d d eZd d ZdS))absolute_importN)hex)open)errorpycompat)rc@seZdZdZdZd!ddZddZedd Zd"d d Z d dZ ddZ ddZ ddZ d#ddZddZddZddZeddZdd ZdS)$revmapz~trivial hg bin hash - linelog rev bidirectional map also stores a flag (uint8) for each revision, and track renames. sREVMAP1NcCs^||_dg|_dg|_i|_dg|_dg|_d|_|r-tj|r'| dS| dSdS)a=create or load the revmap, optionally associate to a file if path is None, the revmap is entirely in-memory. the caller is responsible for locking. concurrent writes to a same file is unsafe. the caller needs to make sure one file is associated to at most one revmap object at a time.Nr) path_rev2hsh _rev2flag_hsh2rev _renamerevs _renamepaths _lastmaxrevosexists_loadflush)selfr r;/usr/lib/python3/dist-packages/hgext/fastannotate/revmap.py__init__<s   zrevmap.__init__cCsV|jdd|_|jdd|_|j|_|jdd|_|jdd|_d|_dS)z>copy the map data from another revmap. do not affect self.pathNr )rrrcopyrrr)rrhsrrrcopyfromSs   zrevmap.copyfromcCst|jdS)z"return max linelog revision numberr)lenr)rrrrmaxrev\sz revmap.maxrevFcCs||jvrtdt|t|tkrtdtt|j}d}|r(|t O}|durC||j dkrC|t O}|j ||j ||j ||j |||j|<|rZ||S)z~add a binary hg hash and return the mapped linelog revision. if flush is True, incrementally update the file. s%r is in revmap alreadyshsh must be %d-char longrNr )rrCorruptedFileErrorrr_hshlenhgerrorProgrammingErrorrsidebranchflagr renameflagrappendrr)rhsh sidebranchr ridxflagrrrr'as,         z revmap.appendcC ||jks |dkr dS|j|S)z>convert linelog revision to hg hash. return None if not found.rN)r rrrevrrrrev2hsh|s zrevmap.rev2hshcCr,)zkget the flag (uint8) for a given linelog revision. return None if revision does not exist. rN)r rr-rrrrev2flags zrevmap.rev2flagcCs2||jks |dkr dSt|j|d}|j|S)zcget the path for a given linelog revision. return None if revision does not exist. rNr)r bisect bisect_rightrr)rr.r*rrrrev2paths zrevmap.rev2pathcCs |j|S)z>convert hg hash to linelog revision. return None if not found.)rget)rr(rrrhsh2revs zrevmap.hsh2revcCs8dg|_dg|_i|_dg|_d|_|r|dSdS)z3make the map empty. if flush is True, write to diskNr r )rrr _rev2pathrr)rrrrrclears z revmap.clearcCs|jsdS|jdkr9t|jd }||jtdt|jD]}| ||q Wdn1s3wYn+t|jd}t|jdt|jD]}| ||qLWdn1s_wY|j |_dS)z write the state down to the fileNr swbrsab) r rrwriteHEADERrxrangerr _writerevr )rfirrrrs$   z revmap.flushc Cs|jsdSd}t}t|jde}|t|j|jkrt|jdd ||}|s.n?t |}t|j }|t @rL| |}|j ||j|||}t||kr[t||j|<|j||j |q&Wdn1swwY|j|_dS)zload state from fileNrrbF)r)r r"rreadrr9rr!r7ordrr& _readcstrrr'rrrr r) rflaglenhshlenr<bufr+r.r r(rrrrs8            z revmap._loadcCsj|j|}|j|}|td||t@r.||}|dur'td|||d||dS)zappend a revision data to fileBNscannot find path for %s) rrr8structpackr&r3rr!)rr.r<r+r(r rrrr;s   zrevmap._writerevcCs4d} |d}|st|dkr |S||7}q)z,read a C-language-like ''-terminated stringr TrrF)r?rr!)r<rDchrrrrAs zrevmap._readcstrcCsht|tr |\}}n ||}}||}|durdS|dur+|||kr+dS||t@dkS)z(fctx or (node, path)) -> bool. test if (node, path) is in the map, and is not in a side branch. f can be either a tuple of (node, path), or a fctx. NFr) isinstancetuplenoder r5r3r0r%)rr<r(r r.rrr __contains__s   zrevmap.__contains__)N)FNF)F)__name__ __module__ __qualname____doc__r9rrpropertyr r'r/r0r3r5r7rrr; staticmethodrArMrrrrr 4s&       r cCsd}z9t|d)}|t tj|ttjkr(| t}WdW|SWdW|S1s4wYW|St yEY|Sw)zreturn the last hash in a revmap, without loading its full content. this is equivalent to `m = revmap(path); m.rev2hsh(m.maxrev)`, but faster. Nr>) rseekr"ioSEEK_ENDtellrr r9r?IOError)r r(r<rrr getlastnodes"     rY) __future__rr1rUrrGmercurial.nodermercurial.pycompatr mercurialrr#rr%r&r"objectr rYrrrrs     H