[PATCH 09 of 11] filecommit: add a fast path to reuse raw revision data

Yuya Nishihara yuya at tcha.org
Fri May 12 09:37:10 EDT 2017


On Wed, 10 May 2017 01:34:28 -0700, Jun Wu wrote:
> # HG changeset patch
> # User Jun Wu <quark at fb.com>
> # Date 1494402182 25200
> #      Wed May 10 00:43:02 2017 -0700
> # Node ID 9d4e0dc68196d113a7dd153748eea1cc731734d3
> # Parent  e4ad86c15b06986e51d4754f3c11bd24cbae30bb
> # Available At https://bitbucket.org/quark-zju/hg-draft
> #              hg pull https://bitbucket.org/quark-zju/hg-draft -r 9d4e0dc68196
> filecommit: add a fast path to reuse raw revision data
> 
> The high-level idea is similar to metadataonlyctx.
> 
> If filelog parents and metadata match, then raw revision data (rawtext,
> rawflags, hash) could be reused. This saves time calculating hash or going
> through flag processors.

Do you have some benchmark results?

> diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
> --- a/mercurial/localrepo.py
> +++ b/mercurial/localrepo.py
> @@ -1433,4 +1433,5 @@ class localrepository(object):
>          meta = {}
>          copy = fctx.renamed()
> +        metamatched = not bool(copy)
>          if copy and copy[0] != fname:
>              # Mark the new revision of this file as a copy of another
> @@ -1476,4 +1477,5 @@ class localrepository(object):
>                  meta["copy"] = cfname
>                  meta["copyrev"] = hex(crev)
> +                metamatched = (crev == copy[1])

I might be wrong, but don't we need to test the equality of cfname?

> +        # reuse rawdata? (skip flagprocessors and hash calculation)
> +        if (metamatched and node is not None
> +            # some filectxs do not support rawdata or flags
> +            and util.safehasattr(fctx, 'rawdata')
> +            and util.safehasattr(fctx, 'rawflags')
> +            # some (external) filelogs do not have addrawrevision
> +            and util.safehasattr(flog, 'addrawrevision')
> +            # parents must match to be able to reuse rawdata
> +            and fctx.filelog().parents(node) == (fparent1, fparent2)):
> +            # node is different from fparents, no need to check manifest flag
> +            changelist.append(fname)
> +            if node in getattr(flog, 'nodemap', ()):
> +                self.ui.debug('reusing %s filelog node (exact match)\n' % fname)
> +                return node

What would happen if flog.nodemap is somehow missing but the exact node exist
in the filelog?

> +            self.ui.debug('reusing %s filelog rawdata\n' % fname)
> +            return flog.addrawrevision(fctx.rawdata(), tr, linkrev, fparent1,
> +                                       fparent2, node, fctx.rawflags())


More information about the Mercurial-devel mailing list