[PATCH 3 of 9] branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David
pierre-yves.david at ens-lyon.org
Wed Dec 26 20:32:59 UTC 2012
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at ens-lyon.org>
# Date 1356276302 -3600
# Node ID 4b098d0339f9e8b1805c4f6ef1d8bcf59f5a6349
# Parent fbf90f3d261f274c1e690026c1a95fd787d3facc
branchmap: takes filtered revision in account for cache calculation
Tracking tipnode and tiprev is not enough to ensure validaty of the cache as
they do not help to distinct cache that ignored various revision bellow tiprev.
To detect such difference, we build a cache of all revision ignored. This hash
is then used when checking validity of a cache for a repo.
diff --git a/mercurial/branchmap.py b/mercurial/branchmap.py
--- a/mercurial/branchmap.py
+++ b/mercurial/branchmap.py
@@ -5,10 +5,11 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
from node import bin, hex, nullid, nullrev
import encoding
+import util
def read(repo):
try:
f = repo.opener("cache/branchheads")
lines = f.read().split('\n')
@@ -67,22 +68,45 @@ def updatecache(repo):
repo._branchcache = partial
class branchcache(dict):
"""A dict like object that hold branches heads cache"""
- def __init__(self, entries=(), tipnode=nullid, tiprev=nullrev):
+ def __init__(self, entries=(), tipnode=nullid, tiprev=nullrev,
+ filtered=None):
super(branchcache, self).__init__(entries)
self.tipnode = tipnode
self.tiprev = tiprev
+ self.filtered = filtered
+
+ def _hashfiltered(self, repo):
+ """build hash of revision filtered in the current cache
+
+ Tracking tipnode and tiprev is not enough to ensure validaty of the
+ cache as they do not help to distinct cache that ignored various
+ revision bellow tiprev.
+
+ To detect such difference, we build a cache of all revision ignored."""
+ cl = repo.changelog
+ if not cl.filteredrevs:
+ return None
+ key = None
+ revs = sorted(r for r in cl.filteredrevs if r <= self.tiprev)
+ if revs:
+ s = util.sha1()
+ for rev in revs:
+ s.update('%s;' % rev)
+ key = s.digest()
+ return key
def validfor(self, repo):
"""Is the cache content valide regarding a repo
- False when cached tipnode are unknown or if we detect a strip.
- True when cache is up to date or a subset of current repo."""
try:
- return self.tipnode == repo.changelog.node(self.tiprev)
+ return ((self.tipnode == repo.changelog.node(self.tiprev))
+ and (self.filtered == self._hashfiltered(repo)))
except IndexError:
return False
def write(self, repo):
@@ -170,5 +194,6 @@ class branchcache(dict):
for heads in self.values():
tiprev = max(cl.rev(node) for node in heads)
if tiprev > self.tiprev:
self.tipnode = cl.node(tiprev)
self.tiprev = tiprev
+ self.filtered = self._hashfiltered(repo)
More information about the Mercurial-devel
mailing list