--- a/hgext/evolve.py Tue Sep 11 11:45:00 2012 +0200
+++ b/hgext/evolve.py Tue Sep 11 12:19:13 2012 +0200
@@ -298,6 +298,8 @@
### Obsolescence Caching Logic ###
#####################################################################
+# IN CORE fb72eec7efd8
+
# Obsolescence related logic can be very slow if we don't have efficient cache.
#
# This section implements a cache mechanism that did not make it into core for
@@ -321,58 +323,65 @@
#: function take a single "repo" argument.
#:
#: Use the `cachefor` decorator to register new cache function
-cachefuncs = {}
-def cachefor(name):
- """Decorator to register a function as computing the cache for a set"""
- def decorator(func):
- assert name not in cachefuncs
- cachefuncs[name] = func
- return func
- return decorator
+try:
+ cachefuncs = obsolete.cachefuncs
+ cachefor = obsolete.cachefor
+ getobscache = obsolete.getobscache
+ clearobscaches = obsolete.clearobscaches
+except AttributeError:
+ cachefuncs = {}
-@cachefor('obsolete')
-def _computeobsoleteset(repo):
- """the set of obsolete revisions"""
- obs = set()
- nm = repo.changelog.nodemap
- for prec in repo.obsstore.precursors:
- rev = nm.get(prec)
- if rev is not None:
- obs.add(rev)
- return set(repo.revs('%ld - public()', obs))
+ def cachefor(name):
+ """Decorator to register a function as computing the cache for a set"""
+ def decorator(func):
+ assert name not in cachefuncs
+ cachefuncs[name] = func
+ return func
+ return decorator
-@cachefor('unstable')
-def _computeunstableset(repo):
- """the set of non obsolete revisions with obsolete parents"""
- return set(repo.revs('(obsolete()::) - obsolete()'))
+ @cachefor('obsolete')
+ def _computeobsoleteset(repo):
+ """the set of obsolete revisions"""
+ obs = set()
+ nm = repo.changelog.nodemap
+ for prec in repo.obsstore.precursors:
+ rev = nm.get(prec)
+ if rev is not None:
+ obs.add(rev)
+ return set(repo.revs('%ld - public()', obs))
-@cachefor('suspended')
-def _computesuspendedset(repo):
- """the set of obsolete parents with non obsolete descendants"""
- return set(repo.revs('obsolete() and obsolete()::unstable()'))
+ @cachefor('unstable')
+ def _computeunstableset(repo):
+ """the set of non obsolete revisions with obsolete parents"""
+ return set(repo.revs('(obsolete()::) - obsolete()'))
-@cachefor('extinct')
-def _computeextinctset(repo):
- """the set of obsolete parents without non obsolete descendants"""
- return set(repo.revs('obsolete() - obsolete()::unstable()'))
+ @cachefor('suspended')
+ def _computesuspendedset(repo):
+ """the set of obsolete parents with non obsolete descendants"""
+ return set(repo.revs('obsolete() and obsolete()::unstable()'))
-@eh.wrapfunction(obsolete.obsstore, '__init__')
-def _initobsstorecache(orig, obsstore, *args, **kwargs):
- """add a cache attribute to obsstore"""
- obsstore.caches = {}
- return orig(obsstore, *args, **kwargs)
+ @cachefor('extinct')
+ def _computeextinctset(repo):
+ """the set of obsolete parents without non obsolete descendants"""
+ return set(repo.revs('obsolete() - obsolete()::unstable()'))
+
+ @eh.wrapfunction(obsolete.obsstore, '__init__')
+ def _initobsstorecache(orig, obsstore, *args, **kwargs):
+ """add a cache attribute to obsstore"""
+ obsstore.caches = {}
+ return orig(obsstore, *args, **kwargs)
### Cache access
-def getobscache(repo, name):
- """Return the set of revision that belong to the <name> set
+ def getobscache(repo, name):
+ """Return the set of revision that belong to the <name> set
- Such access may compute the set and cache it for future use"""
- if not repo.obsstore:
- return ()
- if name not in repo.obsstore.caches:
- repo.obsstore.caches[name] = cachefuncs[name](repo)
- return repo.obsstore.caches[name]
+ Such access may compute the set and cache it for future use"""
+ if not repo.obsstore:
+ return ()
+ if name not in repo.obsstore.caches:
+ repo.obsstore.caches[name] = cachefuncs[name](repo)
+ return repo.obsstore.caches[name]
### Cache clean up
#
@@ -384,85 +393,85 @@
# - strip is used a repo
-def clearobscaches(repo):
- """Remove all obsolescence related cache from a repo
+ def clearobscaches(repo):
+ """Remove all obsolescence related cache from a repo
- This remove all cache in obsstore is the obsstore already exist on the
- repo.
+ This remove all cache in obsstore is the obsstore already exist on the
+ repo.
- (We could be smarter here)"""
- if 'obsstore' in repo._filecache:
- repo.obsstore.caches.clear()
+ (We could be smarter here)"""
+ if 'obsstore' in repo._filecache:
+ repo.obsstore.caches.clear()
-@eh.wrapfunction(localrepo.localrepository, 'addchangegroup') # new changeset
-@eh.wrapfunction(phases, 'retractboundary') # phase movement
-@eh.wrapfunction(phases, 'advanceboundary') # phase movement
-@eh.wrapfunction(localrepo.localrepository, 'destroyed') # strip
-def wrapclearcache(orig, repo, *args, **kwargs):
- try:
- return orig(repo, *args, **kwargs)
- finally:
- # we are a bit wide here
- # we could restrict to:
- # advanceboundary + phase==public
- # retractboundary + phase==draft
- clearobscaches(repo)
+ @eh.wrapfunction(localrepo.localrepository, 'addchangegroup') # new changeset
+ @eh.wrapfunction(phases, 'retractboundary') # phase movement
+ @eh.wrapfunction(phases, 'advanceboundary') # phase movement
+ @eh.wrapfunction(localrepo.localrepository, 'destroyed') # strip
+ def wrapclearcache(orig, repo, *args, **kwargs):
+ try:
+ return orig(repo, *args, **kwargs)
+ finally:
+ # we are a bit wide here
+ # we could restrict to:
+ # advanceboundary + phase==public
+ # retractboundary + phase==draft
+ clearobscaches(repo)
-@eh.wrapfunction(obsolete.obsstore, 'add') # new marker
-def clearonadd(orig, obsstore, *args, **kwargs):
- try:
- return orig(obsstore, *args, **kwargs)
- finally:
- obsstore.caches.clear()
+ @eh.wrapfunction(obsolete.obsstore, 'add') # new marker
+ def clearonadd(orig, obsstore, *args, **kwargs):
+ try:
+ return orig(obsstore, *args, **kwargs)
+ finally:
+ obsstore.caches.clear()
### Use the case
# Function in core that could benefic from the cache are overwritten by cache using version
# changectx method
-@eh.addattr(context.changectx, 'unstable')
-def unstable(ctx):
- """is the changeset unstable (have obsolete ancestor)"""
- if ctx.node() is None:
- return False
- return ctx.rev() in getobscache(ctx._repo, 'unstable')
+ @eh.addattr(context.changectx, 'unstable')
+ def unstable(ctx):
+ """is the changeset unstable (have obsolete ancestor)"""
+ if ctx.node() is None:
+ return False
+ return ctx.rev() in getobscache(ctx._repo, 'unstable')
-@eh.addattr(context.changectx, 'extinct')
-def extinct(ctx):
- """is the changeset extinct by other"""
- if ctx.node() is None:
- return False
- return ctx.rev() in getobscache(ctx._repo, 'extinct')
+ @eh.addattr(context.changectx, 'extinct')
+ def extinct(ctx):
+ """is the changeset extinct by other"""
+ if ctx.node() is None:
+ return False
+ return ctx.rev() in getobscache(ctx._repo, 'extinct')
# revset
-@eh.revset('obsolete')
-def revsetobsolete(repo, subset, x):
- """``obsolete()``
- Changeset is obsolete.
- """
- args = revset.getargs(x, 0, 0, 'obsolete takes no argument')
- obsoletes = getobscache(repo, 'obsolete')
- return [r for r in subset if r in obsoletes]
+ @eh.revset('obsolete')
+ def revsetobsolete(repo, subset, x):
+ """``obsolete()``
+ Changeset is obsolete.
+ """
+ args = revset.getargs(x, 0, 0, 'obsolete takes no argument')
+ obsoletes = getobscache(repo, 'obsolete')
+ return [r for r in subset if r in obsoletes]
-@eh.revset('unstable')
-def revsetunstable(repo, subset, x):
- """``unstable()``
- Unstable changesets are non-obsolete with obsolete ancestors.
- """
- args = revset.getargs(x, 0, 0, 'unstable takes no arguments')
- unstables = getobscache(repo, 'unstable')
- return [r for r in subset if r in unstables]
+ @eh.revset('unstable')
+ def revsetunstable(repo, subset, x):
+ """``unstable()``
+ Unstable changesets are non-obsolete with obsolete ancestors.
+ """
+ args = revset.getargs(x, 0, 0, 'unstable takes no arguments')
+ unstables = getobscache(repo, 'unstable')
+ return [r for r in subset if r in unstables]
-@eh.revset('extinct')
-def revsetextinct(repo, subset, x):
- """``extinct()``
- Obsolete changesets with obsolete descendants only.
- """
- args = revset.getargs(x, 0, 0, 'extinct takes no arguments')
- extincts = getobscache(repo, 'extinct')
- return [r for r in subset if r in extincts]
+ @eh.revset('extinct')
+ def revsetextinct(repo, subset, x):
+ """``extinct()``
+ Obsolete changesets with obsolete descendants only.
+ """
+ args = revset.getargs(x, 0, 0, 'extinct takes no arguments')
+ extincts = getobscache(repo, 'extinct')
+ return [r for r in subset if r in extincts]
#####################################################################
### Complete troubles computation logic ###