comparison mercurial/revlog.py @ 4983:4dbcfc6e359e

revlog: pull chunkcache back into revlog
author Matt Mackall <mpm@selenic.com>
date Mon, 23 Jul 2007 20:44:08 -0500
parents 9672e3c42b0c
children b4066fcbd6ba
comparison
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