[PATCH] Optimize node-to-node localrepo.status
Matt Mackall
mpm at selenic.com
Fri May 4 12:27:52 CDT 2012
On Wed, 2012-05-02 at 21:15 -0400, Jesse Glick wrote:
> # HG changeset patch
> # User Jesse Glick <jesse.glick at oracle.com>
> # Date 1336007415 14400
> # Branch stable
> # Node ID 419630251325c7d081fddd48e816da2cfaaaae51
> # Parent 979b1b7340fba32b4d7f499e6d89093758147520
> Optimize node-to-node localrepo.status.
See bulletpoint 3 here:
http://mercurial.selenic.com/wiki/ContributingChanges
> Templating with {file_mods}/{file_adds}/{file_dels} calls this a lot. For a
> large repo like NetBeans main, the command used by the Hudson plugin for
> Mercurial to calculate its changelog can take a long time. Some simple
> optimizations can reduce this overhead by around 26%, though it is still far
> slower than using only {files}, since localrepo.status() is not cheap.
> (Issue3415 may be another manifestation of the same problem.)
>
> 1. Introduce match.always() to check if a match object always says yes, i.e.
> None was passed in. If so, mfmatches should not bother iterating every file in
> the repository.
..patch 1
> 2. Introduce manifestdict.withflags() to get a set of all files which have any
> flags set, since these are likely to be a minority. Otherwise checking .flags()
> for every file is a lot of dictionary lookups and is quite slow.
..patch 2, please.
> diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
> --- a/mercurial/localrepo.py
> +++ b/mercurial/localrepo.py
> @@ -1334,6 +1334,8 @@
>
> def mfmatches(ctx):
> mf = ctx.manifest().copy()
> + if match.always():
> + return mf
Do we need a copy in this case?
> for fn in mf.keys():
> if not match(fn):
> del mf[fn]
> @@ -1419,10 +1421,11 @@
> mf2 = mfmatches(ctx2)
>
> modified, added, clean = [], [], []
> + withflags = mf1.withflags() | mf2.withflags()
> for fn in mf2:
> if fn in mf1:
> if (fn not in deleted and
> - (mf1.flags(fn) != mf2.flags(fn) or
> + ((fn in withflags and mf1.flags(fn) != mf2.flags(fn)) or
> (mf1[fn] != mf2[fn] and
> (mf2[fn] or ctx1[fn].cmp(ctx2[fn]))))):
> modified.append(fn)
> diff --git a/mercurial/manifest.py b/mercurial/manifest.py
> --- a/mercurial/manifest.py
> +++ b/mercurial/manifest.py
> @@ -19,6 +19,8 @@
> self._flags = flags
> def flags(self, f):
> return self._flags.get(f, "")
> + def withflags(self):
> + return set(self._flags.keys())
> def set(self, f, flags):
> self._flags[f] = flags
> def copy(self):
> diff --git a/mercurial/match.py b/mercurial/match.py
> --- a/mercurial/match.py
> +++ b/mercurial/match.py
> @@ -118,6 +118,8 @@
> return self._files
> def anypats(self):
> return self._anypats
> + def always(self):
> + return False
>
> class exact(match):
> def __init__(self, root, cwd, files):
> @@ -126,6 +128,8 @@
> class always(match):
> def __init__(self, root, cwd):
> match.__init__(self, root, cwd, [])
> + def always(self):
> + return True
>
> class narrowmatcher(match):
> """Adapt a matcher to work on a subdirectory only.
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel
--
Mathematics is the supreme nostalgia of our time.
More information about the Mercurial-devel
mailing list