Patchwork [01,of,10,V2] branchmap: simplify _branchtags using a new _cacheabletip method

login
register
mail settings
Submitter Pierre-Yves David
Date Dec. 20, 2012, 2:08 p.m.
Message ID <aa0e6e4fda8672e936c6.1356012511@crater2.logilab.fr>
Download mbox | patch
Permalink /patch/208/
State Accepted
Commit 569091b938a95cc86017bb150b541c69e90ff3a7
Headers show

Comments

Pierre-Yves David - Dec. 20, 2012, 2:08 p.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at ens-lyon.org>
# Date 1356000770 -3600
# Node ID aa0e6e4fda8672e936c641d1995c62f6309fd311
# Parent  11748167a78ea677eff1ab1ac2a89b9e9cff41f1
branchmap: simplify _branchtags using a new _cacheabletip method

The current _branchtags method is a remnant of an older, much larger function.
Its only remaining role is to help MQ to alter the version of branchcache we
store on disk. As MQ mutates the repository it ensures persistent cache does not
contain anything it is likely to alter.

This changeset makes explicit the stable vs volatile part of repository and
reduces the MQ specific code to the computation of this limit. The main
_branchtags code now handles this possible limit in all cases.

This will help to extract the branchmap logic from the repository.

The new code of _branchtags is a bit duplicated, but as I expect major
refactoring of this section I'm not keen to setup factorisation function here.
Kevin Bullock - Dec. 20, 2012, 4:31 p.m.
On Dec 20, 2012, at 8:08 AM, pierre-yves.david at logilab.fr wrote:

> # HG changeset patch
> # User Pierre-Yves David <pierre-yves.david at ens-lyon.org>
> # Date 1356000770 -3600
> # Node ID aa0e6e4fda8672e936c641d1995c62f6309fd311
> # Parent  11748167a78ea677eff1ab1ac2a89b9e9cff41f1
> branchmap: simplify _branchtags using a new _cacheabletip method

This series LGTM, waiting to hear from others.

pacem in terris / ??? / ?????? / ????????? / ??
Kevin R. Bullock
Augie Fackler - Dec. 21, 2012, 4:43 p.m.
On Dec 20, 2012, at 11:31 AM, Kevin Bullock <kbullock+mercurial at ringworld.org> wrote:

> On Dec 20, 2012, at 8:08 AM, pierre-yves.david at logilab.fr wrote:
> 
>> # HG changeset patch
>> # User Pierre-Yves David <pierre-yves.david at ens-lyon.org>
>> # Date 1356000770 -3600
>> # Node ID aa0e6e4fda8672e936c641d1995c62f6309fd311
>> # Parent  11748167a78ea677eff1ab1ac2a89b9e9cff41f1
>> branchmap: simplify _branchtags using a new _cacheabletip method
> 
> This series LGTM, waiting to hear from others.

Looks good here too. Running tests, and will push once they pass.

> 
> pacem in terris / ??? / ?????? / ????????? / ??
> Kevin R. Bullock
> 
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel

Patch

diff --git a/hgext/mq.py b/hgext/mq.py
--- a/hgext/mq.py
+++ b/hgext/mq.py
@@ -3475,11 +3475,11 @@  def reposetup(ui, repo):
                 else:
                     tags[patch[1]] = patch[0]
 
             return result
 
-        def _branchtags(self, partial, lrev):
+        def _cacheabletip(self):
             q = self.mq
             cl = self.changelog
             qbase = None
             if not q.applied:
                 if getattr(self, '_committingpatch', False):
@@ -3490,29 +3490,14 @@  def reposetup(ui, repo):
                 try:
                     qbase = self.unfiltered().changelog.rev(qbasenode)
                 except error.LookupError:
                     self.ui.warn(_('mq status file refers to unknown node %s\n')
                                  % short(qbasenode))
-            if qbase is None:
-                return super(mqrepo, self)._branchtags(partial, lrev)
-
-            start = lrev + 1
-            if start < qbase:
-                # update the cache (excluding the patches) and save it
-                ctxgen = (self[r] for r in xrange(lrev + 1, qbase))
-                self._updatebranchcache(partial, ctxgen)
-                self._writebranchcache(partial, cl.node(qbase - 1), qbase - 1)
-                start = qbase
-            # if start = qbase, the cache is as updated as it should be.
-            # if start > qbase, the cache includes (part of) the patches.
-            # we might as well use it, but we won't save it.
-
-            # update the cache up to the tip
-            ctxgen = (self[r] for r in xrange(start, len(cl)))
-            self._updatebranchcache(partial, ctxgen)
-
-            return partial
+            ret = super(mqrepo, self)._cacheabletip()
+            if qbase is not None:
+                ret = min(qbase - 1, ret)
+            return ret
 
     if repo.local():
         repo.__class__ = mqrepo
 
         repo._phasedefaults.append(mqphasedefaults)
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -630,18 +630,41 @@  class localrepository(object):
         for bookmark, n in self._bookmarks.iteritems():
             if n == node:
                 marks.append(bookmark)
         return sorted(marks)
 
+    def _cacheabletip(self):
+        """tip-most revision stable enought to used in persistent cache
+
+        This function is overwritten by MQ to ensure we do not write cache for
+        a part of the history that will likely change.
+
+        Efficient handling of filtered revision in branchcache should offer a
+        better alternative. But we are using this approach until it is ready.
+        """
+        cl = self.changelog
+        return cl.rev(cl.tip())
+
     def _branchtags(self, partial, lrev):
         # TODO: rename this function?
+        cl = self.changelog
+        catip = self._cacheabletip()
+        # if lrev == catip: cache is already up to date
+        # if lrev >  catip: we have uncachable element in `partial` can't write
+        #                   on disk
+        if lrev < catip:
+            ctxgen = (self[r] for r in cl.revs(lrev + 1, catip))
+            self._updatebranchcache(partial, ctxgen)
+            self._writebranchcache(partial, cl.node(catip), catip)
+            lrev = catip
+        # If cacheable tip were lower than actual tip, we need to update the
+        # cache up to tip. This update (from cacheable to actual tip) is not
+        # written to disk since it's not cacheable.
         tiprev = len(self) - 1
-        if lrev != tiprev:
-            ctxgen = (self[r] for r in self.changelog.revs(lrev + 1, tiprev))
+        if lrev < tiprev:
+            ctxgen = (self[r] for r in cl.revs(lrev + 1, tiprev))
             self._updatebranchcache(partial, ctxgen)
-            self._writebranchcache(partial, self.changelog.tip(), tiprev)
-
         return partial
 
     @unfilteredmethod # Until we get a smarter cache management
     def updatebranchcache(self):
         tip = self.changelog.tip()