##// END OF EJS Templates
stream-clone: avoid opening a revlog in case we do not need it...
Arseniy Alekseyev -
r51565:3b563954 default
parent child Browse files
Show More
@@ -290,6 +290,16 b' class revlog:'
290
290
291 _flagserrorclass = error.RevlogError
291 _flagserrorclass = error.RevlogError
292
292
293 @staticmethod
294 def is_inline_index(header_bytes):
295 header = INDEX_HEADER.unpack(header_bytes)[0]
296
297 _format_flags = header & ~0xFFFF
298 _format_version = header & 0xFFFF
299
300 features = FEATURES_BY_VERSION[_format_version]
301 return features[b'inline'](_format_flags)
302
293 def __init__(
303 def __init__(
294 self,
304 self,
295 opener,
305 opener,
@@ -16,6 +16,9 b' from .i18n import _'
16 from .pycompat import getattr
16 from .pycompat import getattr
17 from .thirdparty import attr
17 from .thirdparty import attr
18 from .node import hex
18 from .node import hex
19 from .revlogutils.constants import (
20 INDEX_HEADER,
21 )
19 from . import (
22 from . import (
20 changelog,
23 changelog,
21 error,
24 error,
@@ -23,6 +26,7 b' from . import ('
23 manifest,
26 manifest,
24 policy,
27 policy,
25 pycompat,
28 pycompat,
29 revlog as revlogmod,
26 util,
30 util,
27 vfs as vfsmod,
31 vfs as vfsmod,
28 )
32 )
@@ -619,44 +623,70 b' class RevlogStoreEntry(BaseStoreEntry):'
619 copies=None,
623 copies=None,
620 max_changeset=None,
624 max_changeset=None,
621 ):
625 ):
622 if repo is None or max_changeset is None:
626 if (
623 return super().get_streams(
627 repo is None
624 repo=repo,
628 or max_changeset is None
625 vfs=vfs,
626 copies=copies,
627 max_changeset=max_changeset,
628 )
629 if any(k.endswith(b'.idx') for k in self._details.keys()):
630 # This use revlog-v2, ignore for now
629 # This use revlog-v2, ignore for now
630 or any(k.endswith(b'.idx') for k in self._details.keys())
631 # This is not inline, no race expected
632 or b'.d' in self._details
633 ):
631 return super().get_streams(
634 return super().get_streams(
632 repo=repo,
635 repo=repo,
633 vfs=vfs,
636 vfs=vfs,
634 copies=copies,
637 copies=copies,
635 max_changeset=max_changeset,
638 max_changeset=max_changeset,
636 )
639 )
637 name_to_ext = {}
640
638 for ext in self._details.keys():
639 name_to_ext[self._path_prefix + ext] = ext
640 name_to_size = {}
641 name_to_size = {}
641 for f in self.files():
642 for f in self.files():
642 name_to_size[f.unencoded_path] = f.file_size(None)
643 name_to_size[f.unencoded_path] = f.file_size(None)
644
643 stream = [
645 stream = [
644 f.get_stream(vfs, copies)
646 f.get_stream(vfs, copies)
645 for f in self.files()
647 for f in self.files()
646 if name_to_ext[f.unencoded_path] not in (b'.d', b'.i')
648 if not f.unencoded_path.endswith(b'.i')
647 ]
649 ]
648
650
649 is_inline = b'.d' not in self._details
651 index_path = self._path_prefix + b'.i'
650
652
651 rl = self.get_revlog_instance(repo).get_revlog()
653 index_file = None
652 rl_stream = rl.get_streams(max_changeset, force_inline=is_inline)
654 try:
655 index_file = vfs(index_path)
656 header = index_file.read(INDEX_HEADER.size)
657 if revlogmod.revlog.is_inline_index(header):
658 size = name_to_size[index_path]
653
659
654 for name, s, size in rl_stream:
660 # no split underneath, just return the stream
655 if name_to_size.get(name, 0) != size:
661 def get_stream():
656 msg = _(b"expected %d bytes but %d provided for %s")
662 fp = index_file
657 msg %= name_to_size.get(name, 0), size, name
663 try:
658 raise error.Abort(msg)
664 fp.seek(0)
659 stream.extend(rl_stream)
665 yield None
666 if size <= 65536:
667 yield fp.read(size)
668 else:
669 yield from util.filechunkiter(fp, limit=size)
670 finally:
671 fp.close()
672
673 s = get_stream()
674 next(s)
675 index_file = None
676 stream.append((index_path, s, size))
677 else:
678 rl = self.get_revlog_instance(repo).get_revlog()
679 rl_stream = rl.get_streams(max_changeset, force_inline=True)
680 for name, s, size in rl_stream:
681 if name_to_size.get(name, 0) != size:
682 msg = _(b"expected %d bytes but %d provided for %s")
683 msg %= name_to_size.get(name, 0), size, name
684 raise error.Abort(msg)
685 stream.extend(rl_stream)
686 finally:
687 if index_file is not None:
688 index_file.close()
689
660 files = self.files()
690 files = self.files()
661 assert len(stream) == len(files), (
691 assert len(stream) == len(files), (
662 stream,
692 stream,
General Comments 0
You need to be logged in to leave comments. Login now