Mercurial > hg
view hgext/fastannotate/support.py @ 41033:b373477948df
revlog: limit base to rev size ratio to 500 instead of 50
While a value of 50 provided large speedup in some case (400s → 7s) it also
creates a slow down for a whole class of revision we are seeing in a private
repository (0.1s → 3s). A value of 500 makes them disappear improving the
total runtime (the slower revision still improve significantly (400s → 21s)).
We need to run a wider array of tests on various repositories to see the
effect on speed and size of different values for this acceptable constant.
However, in the meantime, it seems safer to move back to a less impactful
value.
author | Boris Feld <boris.feld@octobus.net> |
---|---|
date | Wed, 19 Dec 2018 10:54:25 +0100 |
parents | 303dae0136b0 |
children | 876494fd967d |
line wrap: on
line source
# Copyright 2016-present Facebook. All Rights Reserved. # # support: fastannotate support for hgweb, and filectx # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. from __future__ import absolute_import from mercurial import ( context as hgcontext, dagop, extensions, hgweb, patch, util, ) from . import ( context, revmap, ) class _lazyfctx(object): """delegates to fctx but do not construct fctx when unnecessary""" def __init__(self, repo, node, path): self._node = node self._path = path self._repo = repo def node(self): return self._node def path(self): return self._path @util.propertycache def _fctx(self): return context.resolvefctx(self._repo, self._node, self._path) def __getattr__(self, name): return getattr(self._fctx, name) def _convertoutputs(repo, annotated, contents): """convert fastannotate outputs to vanilla annotate format""" # fastannotate returns: [(nodeid, linenum, path)], [linecontent] # convert to what fctx.annotate returns: [annotateline] results = [] fctxmap = {} annotateline = dagop.annotateline for i, (hsh, linenum, path) in enumerate(annotated): if (hsh, path) not in fctxmap: fctxmap[(hsh, path)] = _lazyfctx(repo, hsh, path) # linenum: the user wants 1-based, we have 0-based. lineno = linenum + 1 fctx = fctxmap[(hsh, path)] line = contents[i] results.append(annotateline(fctx=fctx, lineno=lineno, text=line)) return results def _getmaster(fctx): """(fctx) -> str""" return fctx._repo.ui.config('fastannotate', 'mainbranch') or 'default' def _doannotate(fctx, follow=True, diffopts=None): """like the vanilla fctx.annotate, but do it via fastannotate, and make the output format compatible with the vanilla fctx.annotate. may raise Exception, and always return line numbers. """ master = _getmaster(fctx) annotated = contents = None with context.fctxannotatecontext(fctx, follow, diffopts) as ac: try: annotated, contents = ac.annotate(fctx.rev(), master=master, showpath=True, showlines=True) except Exception: ac.rebuild() # try rebuild once fctx._repo.ui.debug('fastannotate: %s: rebuilding broken cache\n' % fctx._path) try: annotated, contents = ac.annotate(fctx.rev(), master=master, showpath=True, showlines=True) except Exception: raise assert annotated and contents return _convertoutputs(fctx._repo, annotated, contents) def _hgwebannotate(orig, fctx, ui): diffopts = patch.difffeatureopts(ui, untrusted=True, section='annotate', whitespace=True) return _doannotate(fctx, diffopts=diffopts) def _fctxannotate(orig, self, follow=False, linenumber=False, skiprevs=None, diffopts=None): if skiprevs: # skiprevs is not supported yet return orig(self, follow, linenumber, skiprevs=skiprevs, diffopts=diffopts) try: return _doannotate(self, follow, diffopts) except Exception as ex: self._repo.ui.debug('fastannotate: falling back to the vanilla ' 'annotate: %r\n' % ex) return orig(self, follow=follow, skiprevs=skiprevs, diffopts=diffopts) def _remotefctxannotate(orig, self, follow=False, skiprevs=None, diffopts=None): # skipset: a set-like used to test if a fctx needs to be downloaded skipset = None with context.fctxannotatecontext(self, follow, diffopts) as ac: skipset = revmap.revmap(ac.revmappath) return orig(self, follow, skiprevs=skiprevs, diffopts=diffopts, prefetchskip=skipset) def replacehgwebannotate(): extensions.wrapfunction(hgweb.webutil, 'annotate', _hgwebannotate) def replacefctxannotate(): extensions.wrapfunction(hgcontext.basefilectx, 'annotate', _fctxannotate)