Mercurial > evolve
changeset 2295:017b971ba28f
perf: adds cachekey utility to validate changelog+obsstore content
We adds more helper about cache key to prepare the arrival of a cache that can
be updated iteratively (similar to branchmap cache)
author | Pierre-Yves David <pierre-yves.david@ens-lyon.org> |
---|---|
date | Mon, 01 May 2017 08:07:05 +0200 |
parents | 75996eafab43 |
children | d6584ce58030 |
files | hgext3rd/evolve/obscache.py |
diffstat | 1 files changed, 75 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/hgext3rd/evolve/obscache.py Mon May 01 08:05:45 2017 +0200 +++ b/hgext3rd/evolve/obscache.py Mon May 01 08:07:05 2017 +0200 @@ -63,3 +63,78 @@ obsstore.__class__ = cachekeyobsstore return obsstore + +def getcachekey(repo): + """get a cache key covering the changesets and obsmarkers content + + IT contains the following data. Combined with 'upgradeneeded' it allows to + do iterative upgrade for cache depending of theses two data. + + The cache key parts are" + - tip-rev, + - tip-node, + - obsstore-length (nb markers), + - obsstore-file-size (in bytes), + - obsstore "cache key" + """ + assert repo.filtername is None + cl = repo.changelog + index, key = repo.obsstore.cachekey() + tiprev = len(cl) - 1 + return (tiprev, + cl.node(tiprev), + len(repo.obsstore), + index, + key) + +def upgradeneeded(repo, key): + """return (valid, start-rev, start-obs-idx) + + 'valid': is "False" if older cache value needs invalidation, + + 'start-rev': first revision not in the cache. None if cache is up to date, + + 'start-obs-idx': index of the first obs-markers not in the cache. None is + up to date. + """ + + # XXX ideally, this function would return a bounded amount of changeset and + # obsmarkers and the associated new cache key. Otherwise we are exposed to + # a race condition between the time the cache is updated and the new cache + # key is computed. (however, we do not want to compute the full new cache + # key in all case because we want to skip reading the obsstore content. We + # could have a smarter implementation here. + # + # In pratice the cache should be updated after each transaction within a + # lock. So we should be fine. We could enforce this with a new repository + # requirement (or fix the race, that is not too hard). + invalid = (False, 0, 0) + if key is None: + return invalid + + ### Is the cache valid ? + keytiprev, keytipnode, keyobslength, keyobssize, keyobskey = key + # check for changelog strip + cl = repo.changelog + tiprev = len(cl) - 1 + if (tiprev < keytiprev + or cl.node(keytiprev) != keytipnode): + return invalid + # check for obsstore strip + obssize, obskey = repo.obsstore.cachekey(index=keyobssize) + if obskey != keyobskey: + return invalid + + ### cache is valid, is there anything to update + + # any new changesets ? + startrev = None + if keytiprev < tiprev: + startrev = keytiprev + 1 + + # any new markers + startidx = None + if keyobssize < obssize: + startidx = keyobslength + + return True, startrev, startidx