hgext/fastannotate/revmap.py
changeset 43076 2372284d9457
parent 42567 4eaf7197a740
child 43077 687b865b95ad
equal deleted inserted replaced
43075:57875cf423c9 43076:2372284d9457
    44 # whether the changeset changes the file path (ie. is a rename)
    44 # whether the changeset changes the file path (ie. is a rename)
    45 renameflag = 2
    45 renameflag = 2
    46 
    46 
    47 # len(mercurial.node.nullid)
    47 # len(mercurial.node.nullid)
    48 _hshlen = 20
    48 _hshlen = 20
       
    49 
    49 
    50 
    50 class revmap(object):
    51 class revmap(object):
    51     """trivial hg bin hash - linelog rev bidirectional map
    52     """trivial hg bin hash - linelog rev bidirectional map
    52 
    53 
    53     also stores a flag (uint8) for each revision, and track renames.
    54     also stores a flag (uint8) for each revision, and track renames.
   155 
   156 
   156     def flush(self):
   157     def flush(self):
   157         """write the state down to the file"""
   158         """write the state down to the file"""
   158         if not self.path:
   159         if not self.path:
   159             return
   160             return
   160         if self._lastmaxrev == -1: # write the entire file
   161         if self._lastmaxrev == -1:  # write the entire file
   161             with open(self.path, 'wb') as f:
   162             with open(self.path, 'wb') as f:
   162                 f.write(self.HEADER)
   163                 f.write(self.HEADER)
   163                 for i in pycompat.xrange(1, len(self._rev2hsh)):
   164                 for i in pycompat.xrange(1, len(self._rev2hsh)):
   164                     self._writerev(i, f)
   165                     self._writerev(i, f)
   165         else: # append incrementally
   166         else:  # append incrementally
   166             with open(self.path, 'ab') as f:
   167             with open(self.path, 'ab') as f:
   167                 for i in pycompat.xrange(self._lastmaxrev + 1,
   168                 for i in pycompat.xrange(
   168                                          len(self._rev2hsh)):
   169                     self._lastmaxrev + 1, len(self._rev2hsh)
       
   170                 ):
   169                     self._writerev(i, f)
   171                     self._writerev(i, f)
   170         self._lastmaxrev = self.maxrev
   172         self._lastmaxrev = self.maxrev
   171 
   173 
   172     def _load(self):
   174     def _load(self):
   173         """load state from file"""
   175         """load state from file"""
   215     def _readcstr(f):
   217     def _readcstr(f):
   216         """read a C-language-like '\0'-terminated string"""
   218         """read a C-language-like '\0'-terminated string"""
   217         buf = ''
   219         buf = ''
   218         while True:
   220         while True:
   219             ch = f.read(1)
   221             ch = f.read(1)
   220             if not ch: # unexpected eof
   222             if not ch:  # unexpected eof
   221                 raise error.CorruptedFileError()
   223                 raise error.CorruptedFileError()
   222             if ch == '\0':
   224             if ch == '\0':
   223                 break
   225                 break
   224             buf += ch
   226             buf += ch
   225         return buf
   227         return buf
   227     def __contains__(self, f):
   229     def __contains__(self, f):
   228         """(fctx or (node, path)) -> bool.
   230         """(fctx or (node, path)) -> bool.
   229         test if (node, path) is in the map, and is not in a side branch.
   231         test if (node, path) is in the map, and is not in a side branch.
   230         f can be either a tuple of (node, path), or a fctx.
   232         f can be either a tuple of (node, path), or a fctx.
   231         """
   233         """
   232         if isinstance(f, tuple): # f: (node, path)
   234         if isinstance(f, tuple):  # f: (node, path)
   233             hsh, path = f
   235             hsh, path = f
   234         else: # f: fctx
   236         else:  # f: fctx
   235             hsh, path = f.node(), f.path()
   237             hsh, path = f.node(), f.path()
   236         rev = self.hsh2rev(hsh)
   238         rev = self.hsh2rev(hsh)
   237         if rev is None:
   239         if rev is None:
   238             return False
   240             return False
   239         if path is not None and path != self.rev2path(rev):
   241         if path is not None and path != self.rev2path(rev):
   240             return False
   242             return False
   241         return (self.rev2flag(rev) & sidebranchflag) == 0
   243         return (self.rev2flag(rev) & sidebranchflag) == 0
       
   244 
   242 
   245 
   243 def getlastnode(path):
   246 def getlastnode(path):
   244     """return the last hash in a revmap, without loading its full content.
   247     """return the last hash in a revmap, without loading its full content.
   245     this is equivalent to `m = revmap(path); m.rev2hsh(m.maxrev)`, but faster.
   248     this is equivalent to `m = revmap(path); m.rev2hsh(m.maxrev)`, but faster.
   246     """
   249     """