[PATCH 5 of 6] branchcache: let localrepo own the revbranchcache instance, save on close

Pierre-Yves David pierre-yves.david at ens-lyon.org
Sun Dec 14 18:29:42 CST 2014



On 12/14/2014 10:34 AM, Mads Kiilerich wrote:
> # HG changeset patch
> # User Mads Kiilerich <madski at unity3d.com>
> # Date 1418581984 -3600
> #      Sun Dec 14 19:33:04 2014 +0100
> # Node ID 186394f5dbf37adf268fa034fc897201fd2dbe0d
> # Parent  a84099ef1a332eb93bc9287d74c64af7e510f90e
> branchcache: let localrepo own the revbranchcache instance, save on close
>
> This seems to be the best of way of making a shared branchcache available
> everywhere, also to read-only operations like revsets.
>
> diff --git a/mercurial/branchmap.py b/mercurial/branchmap.py
> --- a/mercurial/branchmap.py
> +++ b/mercurial/branchmap.py
> @@ -234,15 +234,14 @@
>           cl = repo.changelog
>           # collect new branch entries
>           newbranches = {}
> -        cache = revbranchcache(repo)
> -        getbranchinfoutf8 = cache.branchinfoutf8
> +        getbranchinfoutf8 = repo.revbranchcache.branchinfoutf8
>           for r in revgen:
>               branchutf8, closesbranch = getbranchinfoutf8(r)
>               branch = encoding.tolocal(branchutf8)
>               newbranches.setdefault(branch, []).append(r)
>               if closesbranch:
>                   self._closednodes.add(cl.node(r))
> -        cache.save()
> +        repo.revbranchcache.save()
>
>           # fetch current topological heads to speed up filtering
>           topoheads = set(cl.headrevs())
> diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
> --- a/mercurial/localrepo.py
> +++ b/mercurial/localrepo.py
> @@ -298,7 +298,8 @@
>           self.filteredrevcache = {}
>
>       def close(self):
> -        pass
> +        if hasunfilteredcache(self, 'revbranchcache'):
> +            self.revbranchcache.save()

We should save much sooner than close. It makes it very likely that 
simple longlived reader overwrites data from actual writter. You should 
probably tight some of the saving to the transaction logic to ensure 
cache are updated an coherent most of the time. And find a way to get it 
flushed as soon as possible after massive write.


>
>       def _restrictcapabilities(self, caps):
>           # bundle2 is not ready for prime time, drop it unless explicitly
> @@ -728,6 +729,11 @@
>           repo = (remote and remote.local()) and remote or self
>           return repo[key].branch()
>
> +    @unfilteredpropertycache
> +    def revbranchcache(self):
> +        """persistent cache of revision branch names"""
> +        return branchmap.revbranchcache(self)
> +

You very likely want this to be some sort of filecache to benefit from 
other process update (and reduce le likelyness of process writting on 
each other).

>       def known(self, nodes):
>           nm = self.changelog.nodemap
>           pc = self._phasecache
> diff --git a/mercurial/statichttprepo.py b/mercurial/statichttprepo.py
> --- a/mercurial/statichttprepo.py
> +++ b/mercurial/statichttprepo.py
> @@ -90,6 +90,12 @@
>       def canpush(self):
>           return False
>
> +class statichttprevbranchcache(object):
> +    def __init__(self, repo):
> +        self.branchinfoutf8 = repo.changelog.branchinfoutf8
> +    def save(self):
> +        pass

What about having and vfs attribute set to None in the readonly case? 
(or some way to detect readonly vfs on the vfs themself)

-- 
Pierre-Yves David


More information about the Mercurial-devel mailing list