Mercurial > evolve
changeset 2294:75996eafab43
perf: adds some cache key helper on the obsstore class
This will be useful to allow validating cache depending on obsstore without
parsing the whole obsstore.
author | Pierre-Yves David <pierre-yves.david@ens-lyon.org> |
---|---|
date | Mon, 01 May 2017 08:05:45 +0200 |
parents | 1659b42c28c2 |
children | 017b971ba28f |
files | hgext3rd/evolve/__init__.py hgext3rd/evolve/obscache.py |
diffstat | 2 files changed, 68 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/hgext3rd/evolve/__init__.py Mon May 01 06:06:41 2017 +0200 +++ b/hgext3rd/evolve/__init__.py Mon May 01 08:05:45 2017 +0200 @@ -131,9 +131,10 @@ from . import ( checkheads, debugcmd, - obsexchange, exthelper, metadata, + obscache, + obsexchange, safeguard, utility, ) @@ -167,6 +168,7 @@ eh.merge(obsexchange.eh) eh.merge(checkheads.eh) eh.merge(safeguard.eh) +eh.merge(obscache.eh) uisetup = eh.final_uisetup extsetup = eh.final_extsetup reposetup = eh.final_reposetup
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hgext3rd/evolve/obscache.py Mon May 01 08:05:45 2017 +0200 @@ -0,0 +1,65 @@ +# Code dedicated to an cache around obsolescence property +# +# This module content aims at being upstreamed. +# +# Copyright 2017 Pierre-Yves David <pierre-yves.david@ens-lyon.org> +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + +from . import ( + exthelper, +) + +eh = exthelper.exthelper() + +try: + obsstorefilecache = localrepo.localrepository.obsstore +except AttributeError: + # XXX hg-3.8 compat + # + # mercurial 3.8 has issue with accessing file cache property from their + # cache. This is fix by 36fbd72c2f39fef8ad52d7c559906c2bc388760c in core + # and shipped in 3.9 + obsstorefilecache = localrepo.localrepository.__dict__['obsstore'] + +# obsstore is a filecache so we have do to some spacial dancing +@eh.wrapfunction(obsstorefilecache, 'func') +def obsstorewithcache(orig, repo): + obsstore = orig(repo) + + class cachekeyobsstore(obsstore.__class__): + + _obskeysize = 200 + + def cachekey(self, index=None): + """return (current-length, cachekey) + + 'current-length': is the current length of the obsstore storage file, + 'cachekey' is the hash of the last 200 bytes ending at 'index'. + + if 'index' is unspecified, current obsstore length is used. + Cacheckey will be set to null id if the obstore is empty. + + If the index specified is higher than the current obsstore file + length, cachekey will be set to None.""" + try: + with self.svfs('obsstore') as obsfile: + obsfile.seek(0, 2) + obsstoresize = obsfile.tell() + if index is None: + index = obsstoresize + elif obsstoresize < index: + return obsstoresize, None + actualsize = min(index, self._obskeysize) + obsfile.seek(index - actualsize, 0) + keydata = obsfile.read(actualsize) + return obsstoresize, hashlib.sha1(keydata).digest() + except (OSError, IOError) as e: + if e.errno != errno.ENOENT: + raise + return 0, node.nullid + + obsstore.__class__ = cachekeyobsstore + + return obsstore