Patchwork [08,of,10,V2] branchmap: make update responsible to update the cache key

login
register
mail settings
Submitter Pierre-Yves David
Date Dec. 24, 2012, 1:53 a.m.
Message ID <1b05ffce47bdaff256a4.1356314020@yamac.lan>
Download mbox | patch
Permalink /patch/287/
State Accepted
Commit 1b05ffce47bdaff256a48fabc65bffb63fca9ba5
Headers show

Comments

Pierre-Yves David - Dec. 24, 2012, 1:53 a.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at logilab.fr>
# Date 1356312124 -3600
# Node ID 1b05ffce47bdaff256a48fabc65bffb63fca9ba5
# Parent  3264d3ce53a0fe45c7b484509fbd380bbe82a805
branchmap: make update responsible to update the cache key

The update function have all necessary data to keep the branchcache key
up to date with its value.

This saves assignment to the cache key that each caller of update had to do by
hand.

The strip case is a bit more complicated to handles from inside the function but
I do not expect any impact.

Patch

diff --git a/mercurial/branchmap.py b/mercurial/branchmap.py
--- a/mercurial/branchmap.py
+++ b/mercurial/branchmap.py
@@ -89,21 +89,43 @@  def update(repo, partial, ctxgen):
             ancestors = set(cl.ancestors([latest],
                                                      bheadrevs[0]))
             if ancestors:
                 bheadrevs = [b for b in bheadrevs if b not in ancestors]
         partial[branch] = [cl.node(rev) for rev in bheadrevs]
+        tiprev = max(bheadrevs)
+        if tiprev > partial.tiprev:
+            partial.tipnode = cl.node(tiprev)
+            partial.tiprev = tiprev
+
 
     # There may be branches that cease to exist when the last commit in the
     # branch was stripped.  This code filters them out.  Note that the
     # branch that ceased to exist may not be in newbranches because
     # newbranches is the set of candidate heads, which when you strip the
     # last commit in a branch will be the parent branch.
+    droppednodes = []
     for branch in partial.keys():
         nodes = [head for head in partial[branch]
                  if cl.hasnode(head)]
         if not nodes:
+            droppednodes.extend(nodes)
             del partial[branch]
+    try:
+        node = cl.node(partial.tiprev)
+    except IndexError:
+        node = None
+    if ((partial.tipnode != node)
+        or (partial.tipnode in droppednodes)):
+        # cache key are not valid anymore
+        partial.tipnode = nullid
+        partial.tiprev = nullrev
+        for heads in partial.values():
+            tiprev = max(cl.rev(node) for node in heads)
+            if tiprev > partial.tiprev:
+                partial.tipnode = cl.node(tiprev)
+                partial.tiprev = tiprev
+
 
 def updatecache(repo):
     repo = repo.unfiltered()  # Until we get a smarter cache management
     cl = repo.changelog
     tip = cl.tip()
@@ -119,22 +141,18 @@  def updatecache(repo):
     # if partial.tiprev >  catip: we have uncachable element in `partial` can't
     #                             write on disk
     if partial.tiprev < catip:
         ctxgen = (repo[r] for r in cl.revs(partial.tiprev + 1, catip))
         update(repo, partial, ctxgen)
-        partial.tipnode = cl.node(catip)
-        partial.tiprev = catip
         partial.write(repo)
     # 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(repo) - 1
     if partial.tiprev < tiprev:
         ctxgen = (repo[r] for r in cl.revs(partial.tiprev + 1, tiprev))
         update(repo, partial, ctxgen)
-        partial.tipnode = cl.node(tiprev)
-        partial.tiprev = tiprev
     repo._branchcache = partial
 
 class branchcache(dict):
     """A dict like object that hold branches heads cache"""
 
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1436,12 +1436,10 @@  class localrepository(object):
         if newheadnodes:
             ctxgen = (self[node] for node in newheadnodes
                       if self.changelog.hasnode(node))
             cache = self._branchcache
             branchmap.update(self, cache, ctxgen)
-            cache.tipnode = self.changelog.tip()
-            cache.tiprev = self.changelog.rev(cache.tipnode)
             cache.write(self)
 
         # Ensure the persistent tag cache is updated.  Doing it now
         # means that the tag cache only has to worry about destroyed
         # heads immediately after a strip/rollback.  That in turn