[PATCH 03 of 10] branchmap: add the tipnode (cache key) on the branchcache object

Pierre-Yves David pierre-yves.david at ens-lyon.org
Fri Dec 21 19:48:50 CST 2012


# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at logilab.fr>
# Date 1356137945 -3600
# Node ID ad194a8ab5c15e6d74fe087061ee960f5d6bbf16
# Parent  79db6d40bcedd40c7f27c009459dfe7820893802
branchmap: add the tipnode (cache key) on the branchcache object

Gathering data and cache key paves the way to a lot of simplification.

diff --git a/mercurial/branchmap.py b/mercurial/branchmap.py
--- a/mercurial/branchmap.py
+++ b/mercurial/branchmap.py
@@ -13,11 +13,11 @@ def read(repo):
     try:
         f = repo.opener("cache/branchheads")
         lines = f.read().split('\n')
         f.close()
     except (IOError, OSError):
-        return branchcache(), nullid, nullrev
+        return branchcache(), nullrev
 
     try:
         last, lrev = lines.pop(0).split(" ", 1)
         last, lrev = bin(last), int(lrev)
         if lrev >= len(repo) or repo[lrev].node() != last:
@@ -30,17 +30,18 @@ def read(repo):
             label = encoding.tolocal(label.strip())
             if not node in repo:
                 raise ValueError('invalidating branch cache because node '+
                                  '%s does not exist' % node)
             partial.setdefault(label, []).append(bin(node))
+        partial.tipnode = last
     except KeyboardInterrupt:
         raise
     except Exception, inst:
         if repo.ui.debugflag:
             repo.ui.warn(str(inst), '\n')
-        partial, last, lrev =  branchcache(), nullid, nullrev
-    return partial, last, lrev
+        partial, lrev = branchcache(), nullrev
+    return partial, lrev
 
 def write(repo, branches, tip, tiprev):
     try:
         f = repo.opener("cache/branchheads", "w", atomictemp=True)
         f.write("%s %s\n" % (hex(tip), tiprev))
@@ -113,37 +114,40 @@ def update(repo, partial, ctxgen):
 
 def updatecache(repo):
     repo = repo.unfiltered()  # Until we get a smarter cache management
     cl = repo.changelog
     tip = cl.tip()
-    if repo._branchcache is not None and repo._branchcachetip == tip:
+    partial = repo._branchcache
+    if partial is not None and partial.tipnode == tip:
         return
 
-    oldtip = repo._branchcachetip
-    if oldtip is None or oldtip not in cl.nodemap:
-        partial, last, lrev = read(repo)
+    if partial is None or partial.tipnode not in cl.nodemap:
+        partial, lrev = read(repo)
     else:
-        lrev = cl.rev(oldtip)
-        partial = repo._branchcache
+        lrev = cl.rev(partial.tipnode)
 
     catip = repo._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 = (repo[r] for r in cl.revs(lrev + 1, catip))
         update(repo, partial, ctxgen)
-        write(repo, partial, cl.node(catip), catip)
+        partial.tipnode = cl.node(catip)
+        write(repo, partial, partial.tipnode, 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(repo) - 1
     if lrev < tiprev:
         ctxgen = (repo[r] for r in cl.revs(lrev + 1, tiprev))
         update(repo, partial, ctxgen)
+        partial.tipnode = cl.node(tiprev)
     repo._branchcache = partial
-    repo._branchcachetip = tip
 
 class branchcache(dict):
     """A dict like object that hold branches heads cache"""
 
+    def __init__(self, entries=(), tipnode=nullid):
+        super(branchcache, self).__init__(entries)
+        self.tipnode = tipnode
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -227,11 +227,10 @@ class localrepository(object):
         if create:
             self._writerequirements()
 
 
         self._branchcache = None
-        self._branchcachetip = None
         self.filterpats = {}
         self._datafilters = {}
         self._transref = self._lockref = self._wlockref = None
 
         # A cache for various files under .hg/ that tracks file changes,
@@ -977,11 +976,10 @@ class localrepository(object):
         if '_tagscache' in vars(self):
             # can't use delattr on proxy
             del self.__dict__['_tagscache']
 
         self.unfiltered()._branchcache = None # in UTF-8
-        self.unfiltered()._branchcachetip = None
         self.invalidatevolatilesets()
 
     def invalidatevolatilesets(self):
         self.filteredrevcache.clear()
         obsolete.clearobscaches(self)
@@ -1438,11 +1436,12 @@ class localrepository(object):
         if newheadnodes:
             tiprev = len(self) - 1
             ctxgen = (self[node] for node in newheadnodes
                       if self.changelog.hasnode(node))
             branchmap.update(self, self._branchcache, ctxgen)
-            branchmap.write(self, self._branchcache, self.changelog.tip(),
+            self._branchcache.tipnode = self.changelog.tip()
+            branchmap.write(self, self._branchcache, self._branchcache.tipnode,
                             tiprev)
 
         # 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
@@ -2493,13 +2492,14 @@ class localrepository(object):
                     rbheads.extend(bheads)
 
                 if rbheads:
                     rtiprev = max((int(self.changelog.rev(node))
                             for node in rbheads))
-                    self._branchcache = branchmap.branchcache(rbranchmap)
-                    rtipnode = self._branchcachetip = self[rtiprev].node()
-                    branchmap.write(self, self._branchcache, rtipnode, rtiprev)
+                    cache = branchmap.branchcache(rbranchmap,
+                                                  self[rtiprev].node())
+                    self._branchcache = cache
+                    branchmap.write(self, cache, cache.tipnode, rtiprev)
             self.invalidate()
             return len(self.heads()) + 1
         finally:
             lock.release()
 
diff --git a/mercurial/statichttprepo.py b/mercurial/statichttprepo.py
--- a/mercurial/statichttprepo.py
+++ b/mercurial/statichttprepo.py
@@ -133,11 +133,10 @@ class statichttprepository(localrepo.loc
         self.manifest = manifest.manifest(self.sopener)
         self.changelog = changelog.changelog(self.sopener)
         self._tags = None
         self.nodetagscache = None
         self._branchcache = None
-        self._branchcachetip = None
         self.encodepats = None
         self.decodepats = None
 
     def _restrictcapabilities(self, caps):
         return caps.difference(["pushkey"])


More information about the Mercurial-devel mailing list