[PATCH STABLE] annotate: always adjust linkrev before walking down to parents (issue4623)

Yuya Nishihara yuya at tcha.org
Sat Apr 25 08:58:10 UTC 2015


# HG changeset patch
# User Yuya Nishihara <yuya at tcha.org>
# Date 1429943886 -32400
#      Sat Apr 25 15:38:06 2015 +0900
# Branch stable
# Node ID 1f3991a11e1ecf5082b01585a7f9a6ace11e001c
# Parent  8015a3cf13805a307b43f22d821cad4824d094ea
annotate: always adjust linkrev before walking down to parents (issue4623)

This should avoid the bad performance in the following scenario. Before this
patch, on "hg annotate -r10000", p.rev() would walk changelog from 10000 to 3
because _descendantrev was 10000. With this patch, it walks from 5 to 3.

  1 -- 2 -- 4 -- 5 -- ... -- 10000
    \      'p'  'f'
     - 3   (grafted 3 to 4)
      'p'

repo:    https://hg.mozilla.org/releases/mozilla-beta/#4f80fecda802
command: hg annotate -r b0a57152fd14 browser/app/profile/firefox.js
before:  83.120 secs
after:    3.820 secs

This patch involves extra calls of narrow _adjustlinkrev(), but the cost of
them seems relatively small compared to wide _adjustlinkrev() calls eliminated
by this patch.

repo:    http://selenic.com/repo/hg/#8015a3cf1380
command: hg annotate mercurial/commands.py
before:  7.380 secs
after:   7.320 secs

repo:    https://hg.mozilla.org/mozilla-central/#f214df6ac75f
command: hg annotate layout/generic/nsTextFrame.cpp
before:  5.070 secs
after:   5.050 secs

repo:    https://hg.mozilla.org/releases/mozilla-beta/#4f80fecda802
command: hg annotate -r 4954faa47dd0 gfx/thebes/gfxWindowsPlatform.cpp
before:  1.600 secs
after:   1.620 secs

diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -887,6 +887,11 @@ class basefilectx(object):
         getlog = util.lrucachefunc(lambda x: self._repo.file(x))
 
         def parents(f):
+            # Cut _descendantrev here to mitigate the penalty of lazy linkrev
+            # adjustment. Otherwise, p._adjustlinkrev() would walk changelog
+            # from the topmost introrev (= srcrev) down to p.linkrev() if it
+            # isn't an ancestor of the srcrev.
+            f._changeid
             pl = f.parents()
 
             # Don't return renamed parents if we aren't following.


More information about the Mercurial-devel mailing list