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) |