# HG changeset patch # User Pierre-Yves David # Date 1493618745 -7200 # Node ID 75996eafab43c9954635442cff9de9c2f5d4b234 # Parent 1659b42c28c205b0193d4bf240c786995b5a6749 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. diff -r 1659b42c28c2 -r 75996eafab43 hgext3rd/evolve/__init__.py --- 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 diff -r 1659b42c28c2 -r 75996eafab43 hgext3rd/evolve/obscache.py --- /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 +# +# 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