Skip to content
Snippets Groups Projects
Commit 2f357d053df2 authored by Kyle Lippincott's avatar Kyle Lippincott
Browse files

copies: make calculating lazy for dir move detection's "addedfiles"

The information calculated here was only needed if (a) --debug was specified, or
(b) a directory move was plausibly detected. With tree manifests (especially in
my pathological repo and with our custom setup), pre-calculating the `u1` and
`u2` can be quite slow, and it's not even necessary in many cases. Let's delay
calculating it until we know it's actually necessary. This should have no
observable differences in output.

### Performance

I ran a rebase command in my pathological repo, rebasing two nodes across
several public phase commits, but where no directory copies exist in any of the
paths I'm tracking.

#### Before

```
  Time (mean ± σ):      3.711 s ±  0.061 s    [User: 0.3 ms, System: 1.5 ms]
  Range (min … max):    3.640 s …  3.827 s    10 runs
```

#### After

```
  Time (mean ± σ):     868.3 ms ±  10.1 ms    [User: 0.5 ms, System: 1.2 ms]
  Range (min … max):   856.6 ms … 883.6 ms    10 runs
```

Differential Revision: https://phab.mercurial-scm.org/D9567
parent bdc2bf68f19e
No related branches found
No related tags found
No related merge requests found
...@@ -896,8 +896,14 @@ ...@@ -896,8 +896,14 @@
) )
# find interesting file sets from manifests # find interesting file sets from manifests
addedinm1 = m1.filesnotin(mb, repo.narrowmatch()) cache = []
addedinm2 = m2.filesnotin(mb, repo.narrowmatch())
u1 = sorted(addedinm1 - addedinm2) def _get_addedfiles(idx):
u2 = sorted(addedinm2 - addedinm1) if not cache:
addedinm1 = m1.filesnotin(mb, repo.narrowmatch())
addedinm2 = m2.filesnotin(mb, repo.narrowmatch())
u1 = sorted(addedinm1 - addedinm2)
u2 = sorted(addedinm2 - addedinm1)
cache.extend((u1, u2))
return cache[idx]
...@@ -903,7 +909,7 @@ ...@@ -903,7 +909,7 @@
header = b" unmatched files in %s" u1fn = lambda: _get_addedfiles(0)
if u1: u2fn = lambda: _get_addedfiles(1)
repo.ui.debug(b"%s:\n %s\n" % (header % b'local', b"\n ".join(u1))) if repo.ui.debugflag:
if u2: u1 = u1fn()
repo.ui.debug(b"%s:\n %s\n" % (header % b'other', b"\n ".join(u2))) u2 = u2fn()
...@@ -909,5 +915,14 @@ ...@@ -909,5 +915,14 @@
if repo.ui.debugflag: header = b" unmatched files in %s"
if u1:
repo.ui.debug(
b"%s:\n %s\n" % (header % b'local', b"\n ".join(u1))
)
if u2:
repo.ui.debug(
b"%s:\n %s\n" % (header % b'other', b"\n ".join(u2))
)
renamedeleteset = set() renamedeleteset = set()
divergeset = set() divergeset = set()
for dsts in diverge.values(): for dsts in diverge.values():
...@@ -941,8 +956,8 @@ ...@@ -941,8 +956,8 @@
repo.ui.debug(b" checking for directory renames\n") repo.ui.debug(b" checking for directory renames\n")
dirmove1, movewithdir2 = _dir_renames(repo, c1, copy1, copies1, u2) dirmove1, movewithdir2 = _dir_renames(repo, c1, copy1, copies1, u2fn)
dirmove2, movewithdir1 = _dir_renames(repo, c2, copy2, copies2, u1) dirmove2, movewithdir1 = _dir_renames(repo, c2, copy2, copies2, u1fn)
branch_copies1 = branch_copies(copy1, renamedelete1, dirmove1, movewithdir1) branch_copies1 = branch_copies(copy1, renamedelete1, dirmove1, movewithdir1)
branch_copies2 = branch_copies(copy2, renamedelete2, dirmove2, movewithdir2) branch_copies2 = branch_copies(copy2, renamedelete2, dirmove2, movewithdir2)
...@@ -950,10 +965,10 @@ ...@@ -950,10 +965,10 @@
return branch_copies1, branch_copies2, diverge return branch_copies1, branch_copies2, diverge
def _dir_renames(repo, ctx, copy, fullcopy, addedfiles): def _dir_renames(repo, ctx, copy, fullcopy, addedfilesfn):
"""Finds moved directories and files that should move with them. """Finds moved directories and files that should move with them.
ctx: the context for one of the sides ctx: the context for one of the sides
copy: files copied on the same side (as ctx) copy: files copied on the same side (as ctx)
fullcopy: files copied on the same side (as ctx), including those that fullcopy: files copied on the same side (as ctx), including those that
merge.manifestmerge() won't care about merge.manifestmerge() won't care about
...@@ -954,10 +969,11 @@ ...@@ -954,10 +969,11 @@
"""Finds moved directories and files that should move with them. """Finds moved directories and files that should move with them.
ctx: the context for one of the sides ctx: the context for one of the sides
copy: files copied on the same side (as ctx) copy: files copied on the same side (as ctx)
fullcopy: files copied on the same side (as ctx), including those that fullcopy: files copied on the same side (as ctx), including those that
merge.manifestmerge() won't care about merge.manifestmerge() won't care about
addedfiles: added files on the other side (compared to ctx) addedfilesfn: function returning added files on the other side (compared to
ctx)
""" """
# generate a directory move map # generate a directory move map
invalid = set() invalid = set()
...@@ -997,7 +1013,7 @@ ...@@ -997,7 +1013,7 @@
movewithdir = {} movewithdir = {}
# check unaccounted nonoverlapping files against directory moves # check unaccounted nonoverlapping files against directory moves
for f in addedfiles: for f in addedfilesfn():
if f not in fullcopy: if f not in fullcopy:
for d in dirmove: for d in dirmove:
if f.startswith(d): if f.startswith(d):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment