mercurial/revlog.py
changeset 4983 4dbcfc6e359e
parent 4982 9672e3c42b0c
child 4984 b4066fcbd6ba
equal deleted inserted replaced
4982:9672e3c42b0c 4983:4dbcfc6e359e
   305 def offset_type(offset, type):
   305 def offset_type(offset, type):
   306     return long(long(offset) << 16 | type)
   306     return long(long(offset) << 16 | type)
   307 
   307 
   308 class revlogoldio(object):
   308 class revlogoldio(object):
   309     def __init__(self):
   309     def __init__(self):
   310         self.chunkcache = None
       
   311         self.size = struct.calcsize(indexformatv0)
   310         self.size = struct.calcsize(indexformatv0)
   312 
   311 
   313     def parseindex(self, fp, st, inline):
   312     def parseindex(self, fp, st, inline):
   314         s = self.size
   313         s = self.size
   315         index = []
   314         index = []
   326                   nodemap[e[4]], nodemap[e[5]], e[6])
   325                   nodemap[e[4]], nodemap[e[5]], e[6])
   327             index.append(e2)
   326             index.append(e2)
   328             nodemap[e[6]] = n
   327             nodemap[e[6]] = n
   329             n += 1
   328             n += 1
   330 
   329 
   331         return index, nodemap
   330         return index, nodemap, None
   332 
   331 
   333 class revlogio(object):
   332 class revlogio(object):
   334     def __init__(self):
   333     def __init__(self):
   335         self.chunkcache = None
       
   336         self.size = struct.calcsize(indexformatng)
   334         self.size = struct.calcsize(indexformatng)
   337 
   335 
   338     def parseindex(self, fp, st, inline):
   336     def parseindex(self, fp, st, inline):
   339         if (lazyparser.safe_to_use and not inline and
   337         if (lazyparser.safe_to_use and not inline and
   340             st and st.st_size > 1000000):
   338             st and st.st_size > 1000000):
   344             nodemap = lazymap(parser)
   342             nodemap = lazymap(parser)
   345             e = list(index[0])
   343             e = list(index[0])
   346             type = gettype(e[0])
   344             type = gettype(e[0])
   347             e[0] = offset_type(0, type)
   345             e[0] = offset_type(0, type)
   348             index[0] = e
   346             index[0] = e
   349             return index, nodemap
   347             return index, nodemap, None
   350 
   348 
   351         s = self.size
   349         s = self.size
       
   350         cache = None
   352         index = []
   351         index = []
   353         nodemap =  {nullid: nullrev}
   352         nodemap =  {nullid: nullrev}
   354         n = off = 0
   353         n = off = 0
   355         # if we're not using lazymap, always read the whole index
   354         # if we're not using lazymap, always read the whole index
   356         data = fp.read()
   355         data = fp.read()
   357         l = len(data)
   356         l = len(data)
   358         if inline:
   357         if inline:
   359             self.chunkcache = (0, data)
   358             cache = (0, data)
   360         while off + s <= l:
   359         while off + s <= l:
   361             e = struct.unpack(indexformatng, data[off:off + s])
   360             e = struct.unpack(indexformatng, data[off:off + s])
   362             index.append(e)
   361             index.append(e)
   363             nodemap[e[7]] = n
   362             nodemap[e[7]] = n
   364             n += 1
   363             n += 1
   371         e = list(index[0])
   370         e = list(index[0])
   372         type = gettype(e[0])
   371         type = gettype(e[0])
   373         e[0] = offset_type(0, type)
   372         e[0] = offset_type(0, type)
   374         index[0] = e
   373         index[0] = e
   375 
   374 
   376         return index, nodemap
   375         return index, nodemap, cache
   377 
   376 
   378 class revlog(object):
   377 class revlog(object):
   379     """
   378     """
   380     the underlying revision storage object
   379     the underlying revision storage object
   381 
   380 
   411         self.datafile = indexfile[:-2] + ".d"
   410         self.datafile = indexfile[:-2] + ".d"
   412         self.opener = opener
   411         self.opener = opener
   413 
   412 
   414         self.indexstat = None
   413         self.indexstat = None
   415         self.cache = None
   414         self.cache = None
       
   415         self._chunkcache = None
   416         self.defversion = REVLOG_DEFAULT_VERSION
   416         self.defversion = REVLOG_DEFAULT_VERSION
   417         if hasattr(opener, "defversion"):
   417         if hasattr(opener, "defversion"):
   418             self.defversion = opener.defversion
   418             self.defversion = opener.defversion
   419             if self.defversion & REVLOGNG:
   419             if self.defversion & REVLOGNG:
   420                 self.defversion |= REVLOGNGINLINEDATA
   420                 self.defversion |= REVLOGNGINLINEDATA
   465         self.index = []
   465         self.index = []
   466         self._io = revlogio()
   466         self._io = revlogio()
   467         if self.version == REVLOGV0:
   467         if self.version == REVLOGV0:
   468             self._io = revlogoldio()
   468             self._io = revlogoldio()
   469         if i:
   469         if i:
   470             self.index, self.nodemap = self._io.parseindex(f, st, self._inline)
   470             d = self._io.parseindex(f, st, self._inline)
       
   471             self.index, self.nodemap, self._chunkcache = d
   471         # add the magic null revision at -1
   472         # add the magic null revision at -1
   472         self.index.append((0, 0, 0, -1, -1, -1, -1, nullid))
   473         self.index.append((0, 0, 0, -1, -1, -1, -1, nullid))
   473 
   474 
   474     def _loadindex(self, start, end):
   475     def _loadindex(self, start, end):
   475         """load a block of indexes all at once from the lazy parser"""
   476         """load a block of indexes all at once from the lazy parser"""
   853                 if inline:
   854                 if inline:
   854                     df = self.opener(self.indexfile)
   855                     df = self.opener(self.indexfile)
   855                 else:
   856                 else:
   856                     df = self.opener(self.datafile)
   857                     df = self.opener(self.datafile)
   857             df.seek(start)
   858             df.seek(start)
   858             self._io.chunkcache = (start, df.read(cache_length))
   859             self._chunkcache = (start, df.read(cache_length))
   859 
   860 
   860         if not self._io.chunkcache:
   861         if not self._chunkcache:
   861             loadcache(df)
   862             loadcache(df)
   862 
   863 
   863         cache_start = self._io.chunkcache[0]
   864         cache_start = self._chunkcache[0]
   864         cache_end = cache_start + len(self._io.chunkcache[1])
   865         cache_end = cache_start + len(self._chunkcache[1])
   865         if start >= cache_start and end <= cache_end:
   866         if start >= cache_start and end <= cache_end:
   866             # it is cached
   867             # it is cached
   867             offset = start - cache_start
   868             offset = start - cache_start
   868         else:
   869         else:
   869             loadcache(df)
   870             loadcache(df)
   870             offset = 0
   871             offset = 0
   871 
   872 
   872         return decompress(self._io.chunkcache[1][offset:offset + length])
   873         return decompress(self._chunkcache[1][offset:offset + length])
   873 
   874 
   874     def delta(self, node):
   875     def delta(self, node):
   875         """return or calculate a delta between a node and its predecessor"""
   876         """return or calculate a delta between a node and its predecessor"""
   876         r = self.rev(node)
   877         r = self.rev(node)
   877         return self.revdiff(r - 1, r)
   878         return self.revdiff(r - 1, r)
   973         # if we don't call rename, the temp file will never replace the
   974         # if we don't call rename, the temp file will never replace the
   974         # real index
   975         # real index
   975         fp.rename()
   976         fp.rename()
   976 
   977 
   977         tr.replace(self.indexfile, trindex * calc)
   978         tr.replace(self.indexfile, trindex * calc)
   978         self._io.chunkcache = None
   979         self._chunkcache = None
   979 
   980 
   980     def addrevision(self, text, transaction, link, p1, p2, d=None):
   981     def addrevision(self, text, transaction, link, p1, p2, d=None):
   981         """add a revision to the log
   982         """add a revision to the log
   982 
   983 
   983         text - the revision data to add
   984         text - the revision data to add
  1231         indexf = self.opener(self.indexfile, "a")
  1232         indexf = self.opener(self.indexfile, "a")
  1232         indexf.truncate(end)
  1233         indexf.truncate(end)
  1233 
  1234 
  1234         # then reset internal state in memory to forget those revisions
  1235         # then reset internal state in memory to forget those revisions
  1235         self.cache = None
  1236         self.cache = None
  1236         self._io.chunkcache = None
  1237         self._chunkcache = None
  1237         for x in xrange(rev, self.count()):
  1238         for x in xrange(rev, self.count()):
  1238             del self.nodemap[self.node(x)]
  1239             del self.nodemap[self.node(x)]
  1239 
  1240 
  1240         del self.index[rev:-1]
  1241         del self.index[rev:-1]
  1241 
  1242