mercurial/revlog.py
changeset 8314 57a41c08feab
parent 8312 b87a50b7125c
child 8315 c8493310ad9b
equal deleted inserted replaced
8313:b695392491e7 8314:57a41c08feab
    28 REVLOGNG = 1
    28 REVLOGNG = 1
    29 REVLOGNGINLINEDATA = (1 << 16)
    29 REVLOGNGINLINEDATA = (1 << 16)
    30 REVLOG_DEFAULT_FLAGS = REVLOGNGINLINEDATA
    30 REVLOG_DEFAULT_FLAGS = REVLOGNGINLINEDATA
    31 REVLOG_DEFAULT_FORMAT = REVLOGNG
    31 REVLOG_DEFAULT_FORMAT = REVLOGNG
    32 REVLOG_DEFAULT_VERSION = REVLOG_DEFAULT_FORMAT | REVLOG_DEFAULT_FLAGS
    32 REVLOG_DEFAULT_VERSION = REVLOG_DEFAULT_FORMAT | REVLOG_DEFAULT_FLAGS
       
    33 
       
    34 _prereadsize = 1048576
    33 
    35 
    34 RevlogError = error.RevlogError
    36 RevlogError = error.RevlogError
    35 LookupError = error.LookupError
    37 LookupError = error.LookupError
    36 
    38 
    37 def getoffset(q):
    39 def getoffset(q):
   313 
   315 
   314 class revlogoldio(object):
   316 class revlogoldio(object):
   315     def __init__(self):
   317     def __init__(self):
   316         self.size = struct.calcsize(indexformatv0)
   318         self.size = struct.calcsize(indexformatv0)
   317 
   319 
   318     def parseindex(self, fp, inline):
   320     def parseindex(self, fp, data, inline):
   319         s = self.size
   321         s = self.size
   320         index = []
   322         index = []
   321         nodemap =  {nullid: nullrev}
   323         nodemap =  {nullid: nullrev}
   322         n = off = 0
   324         n = off = 0
   323         data = fp.read()
   325         if len(data) < _prereadsize:
       
   326             data += fp.read() # read the rest
   324         l = len(data)
   327         l = len(data)
   325         while off + s <= l:
   328         while off + s <= l:
   326             cur = data[off:off + s]
   329             cur = data[off:off + s]
   327             off += s
   330             off += s
   328             e = _unpack(indexformatv0, cur)
   331             e = _unpack(indexformatv0, cur)
   356 
   359 
   357 class revlogio(object):
   360 class revlogio(object):
   358     def __init__(self):
   361     def __init__(self):
   359         self.size = struct.calcsize(indexformatng)
   362         self.size = struct.calcsize(indexformatng)
   360 
   363 
   361     def parseindex(self, fp, inline):
   364     def parseindex(self, fp, data, inline):
   362         try:
   365         try:
   363             size = util.fstat(fp).st_size
   366             size = len(data)
       
   367             if size == _prereadsize:
       
   368                 size = util.fstat(fp).st_size
   364         except AttributeError:
   369         except AttributeError:
   365             size = 0
   370             size = 0
   366 
   371 
   367         if util.openhardlinks() and not inline and size > 1000000:
   372         if util.openhardlinks() and not inline and size > _prereadsize:
   368             # big index, let's parse it on demand
   373             # big index, let's parse it on demand
   369             parser = lazyparser(fp, size)
   374             parser = lazyparser(fp, size)
   370             index = lazyindex(parser)
   375             index = lazyindex(parser)
   371             nodemap = lazymap(parser)
   376             nodemap = lazymap(parser)
   372             e = list(index[0])
   377             e = list(index[0])
   373             type = gettype(e[0])
   378             type = gettype(e[0])
   374             e[0] = offset_type(0, type)
   379             e[0] = offset_type(0, type)
   375             index[0] = e
   380             index[0] = e
   376             return index, nodemap, None
   381             return index, nodemap, None
   377 
   382 
   378         data = fp.read()
       
   379         # call the C implementation to parse the index data
   383         # call the C implementation to parse the index data
   380         index, nodemap, cache = parsers.parse_index(data, inline)
   384         index, nodemap, cache = parsers.parse_index(data, inline)
   381         return index, nodemap, cache
   385         return index, nodemap, cache
   382 
   386 
   383     def packentry(self, entry, node, version, rev):
   387     def packentry(self, entry, node, version, rev):
   430         if hasattr(opener, "defversion"):
   434         if hasattr(opener, "defversion"):
   431             v = opener.defversion
   435             v = opener.defversion
   432             if v & REVLOGNG:
   436             if v & REVLOGNG:
   433                 v |= REVLOGNGINLINEDATA
   437                 v |= REVLOGNGINLINEDATA
   434 
   438 
   435         i = ""
   439         i = ''
   436         try:
   440         try:
   437             f = self.opener(self.indexfile)
   441             f = self.opener(self.indexfile)
   438             i = f.read(4)
   442             i = f.read(_prereadsize)
   439             f.seek(0)
       
   440             if len(i) > 0:
   443             if len(i) > 0:
   441                 v = struct.unpack(versionformat, i)[0]
   444                 v = struct.unpack(versionformat, i[:4])[0]
   442         except IOError, inst:
   445         except IOError, inst:
   443             if inst.errno != errno.ENOENT:
   446             if inst.errno != errno.ENOENT:
   444                 raise
   447                 raise
   445 
   448 
   446         self.version = v
   449         self.version = v
   460         self._io = revlogio()
   463         self._io = revlogio()
   461         if self.version == REVLOGV0:
   464         if self.version == REVLOGV0:
   462             self._io = revlogoldio()
   465             self._io = revlogoldio()
   463         if i:
   466         if i:
   464             try:
   467             try:
   465                 d = self._io.parseindex(f, self._inline)
   468                 d = self._io.parseindex(f, i, self._inline)
   466             except (ValueError, IndexError), e:
   469             except (ValueError, IndexError), e:
   467                 raise RevlogError(_("index %s is corrupted") % (self.indexfile))
   470                 raise RevlogError(_("index %s is corrupted") % (self.indexfile))
   468             self.index, self.nodemap, self._chunkcache = d
   471             self.index, self.nodemap, self._chunkcache = d
   469 
   472 
   470         # add the magic null revision at -1 (if it hasn't been done already)
   473         # add the magic null revision at -1 (if it hasn't been done already)