Mercurial > hg-stable
changeset 18101:a464deecc9dd
clfilter: add a cache on repo for set of revision to filter for a given set.
Recomputing the filtered revisions at every access to changelog is far too
expensive. This changeset introduce a cache for this information. This cache is
hold by the repository (unfiltered repository) and invalidated when necessary.
This cache is not a protected attribute (leading _) because some logic that
invalidate it is not held by the local repo itself.
author | Pierre-Yves David <pierre-yves.david@ens-lyon.org> |
---|---|
date | Thu, 20 Dec 2012 17:14:07 +0100 |
parents | 3a6ddacb7198 |
children | 3c7b67b76190 |
files | mercurial/localrepo.py mercurial/obsolete.py mercurial/phases.py mercurial/repoview.py |
diffstat | 4 files changed, 19 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/localrepo.py Thu Dec 20 15:32:42 2012 +0100 +++ b/mercurial/localrepo.py Thu Dec 20 17:14:07 2012 +0100 @@ -239,6 +239,15 @@ # Maps a property name to its util.filecacheentry self._filecache = {} + # hold sets of revision to be filtered + # should be cleared when something might have changed the filter value: + # - new changesets, + # - phase change, + # - new obsolescence marker, + # - working directory parent change, + # - bookmark changes + self.filteredrevcache = {} + def close(self): pass @@ -1093,6 +1102,7 @@ self.unfiltered()._branchcache = None # in UTF-8 self.unfiltered()._branchcachetip = None obsolete.clearobscaches(self) + self.filteredrevcache.clear() def invalidatedirstate(self): '''Invalidates the dirstate, causing the next call to dirstate @@ -1858,6 +1868,7 @@ if key.startswith('dump'): data = base85.b85decode(remoteobs[key]) self.obsstore.mergemarkers(tr, data) + self.filteredrevcache.clear() if tr is not None: tr.close() finally: @@ -2470,6 +2481,7 @@ " with %d changes to %d files%s\n") % (changesets, revisions, files, htext)) obsolete.clearobscaches(self) + self.filteredrevcache.clear() if changesets > 0: p = lambda: cl.writepending() and self.root or ""
--- a/mercurial/obsolete.py Thu Dec 20 15:32:42 2012 +0100 +++ b/mercurial/obsolete.py Thu Dec 20 17:14:07 2012 +0100 @@ -738,6 +738,7 @@ if nprec in nsucs: raise util.Abort("changeset %s cannot obsolete itself" % prec) repo.obsstore.create(tr, nprec, nsucs, flag, metadata) + repo.filteredrevcache.clear() tr.close() finally: tr.release()
--- a/mercurial/phases.py Thu Dec 20 15:32:42 2012 +0100 +++ b/mercurial/phases.py Thu Dec 20 17:14:07 2012 +0100 @@ -249,6 +249,7 @@ if targetphase != 0: self.retractboundary(repo, targetphase, delroots) obsolete.clearobscaches(repo) + repo.filteredrevcache.clear() def retractboundary(self, repo, targetphase, nodes): # Be careful to preserve shallow-copied values: do not update @@ -267,6 +268,7 @@ currentroots.intersection_update(ctx.node() for ctx in ctxs) self._updateroots(targetphase, currentroots) obsolete.clearobscaches(repo) + repo.filteredrevcache.clear() def advanceboundary(repo, targetphase, nodes): """Add nodes to a phase changing other nodes phases if necessary.
--- a/mercurial/repoview.py Thu Dec 20 15:32:42 2012 +0100 +++ b/mercurial/repoview.py Thu Dec 20 17:14:07 2012 +0100 @@ -13,7 +13,10 @@ def filteredrevs(repo, filtername): """returns set of filtered revision for this filter name""" - return filtertable[filtername](repo.unfiltered()) + if filtername not in repo.filteredrevcache: + func = filtertable[filtername] + repo.filteredrevcache[filtername] = func(repo.unfiltered()) + return repo.filteredrevcache[filtername] class repoview(object): """Provide a read/write view of a repo through a filtered changelog