remotefilelog: speed up prefetch

Summary:
Prefetch had some legacy logic that tried to look at the server to
determine what it needed to fetch. That's expensive, so let's just replace it
with looking at draft() commits. It also had some naive logic that looped over
every file in the manifest and tried to match a pattern. Let's instead use
mf.matches which efficiently avoids traversing unnecessary directories.

This makes prefetch much faster.

Reviewed By: kulshrax

Differential Revision: D22853075

fbshipit-source-id: cf98aa147203c2d0e811b98998b8dc89173943a6
This commit is contained in:
Durham Goode 2020-07-31 22:08:09 -07:00 committed by Facebook GitHub Bot
parent ee7f799cad
commit 9d3d3e9f8e

View File

@ -149,8 +149,7 @@ def wraprepo(repo):
# If we know a rev is on the server, we should fetch the server
# version of those files, since our local file versions might
# become obsolete if the local commits are stripped.
with progress.spinner(self.ui, _("finding outgoing revisions")):
localrevs = self.revs("outgoing(%s)", fallbackpath)
localrevs = self.revs("draft()")
if base is not None and base != nullrev:
serverbase = list(
self.revs("first(reverse(::%s) - %ld)", base, localrevs)
@ -178,25 +177,21 @@ def wraprepo(repo):
ctx = self[rev]
if pats:
m = scmutil.match(ctx, pats, opts)
if matcher is None:
elif matcher is None:
matcher = self.maybesparsematch(rev)
mfnode = ctx.manifestnode()
mfctx = mfl[mfnode]
# Decompressing manifests is expensive.
# When possible, only read the deltas.
p1, p2 = mfctx.parents
if p1 in visited and p2 in visited:
mfdict = mfctx.readnew()
else:
mfdict = mfctx.read()
mf = mfctx.read()
diff = iteritems(mfdict)
diff = []
if pats:
diff = (pf for pf in diff if m(pf[0]))
diff.extend(iteritems(mf.matches(m)))
if matcher:
diff = (pf for pf in diff if matcher(pf[0]))
diff.extend(iteritems(mf.matches(matcher)))
if not pats and not matcher:
diff.extend(iteritems(mf))
if rev not in localrevs:
serverfiles.update(diff)
else: