From patchwork Thu Aug 21 03:20:54 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [4,of,7] obsstore: add relevant markers method From: Pierre-Yves David X-Patchwork-Id: 5541 Message-Id: <06e61fc68d923f5d99dc.1408591254@marginatus.alto.octopoid.net> To: mercurial-devel@selenic.com Cc: Pierre-Yves David Date: Wed, 20 Aug 2014 20:20:54 -0700 # HG changeset patch # User Pierre-Yves David # Date 1408492990 25200 # Tue Aug 19 17:03:10 2014 -0700 # Node ID 06e61fc68d923f5d99dc1960ee278a1aaf3aa5f1 # Parent 0e700b1c54043586d946b33202da450dc46f9c06 obsstore: add relevant markers method We add a ``relevantmarkers`` methods to fetch all markers that seems relevant to a set of node. See function documentation about how this set is computed. This will let us exchange only the markers that seems "relevant" to the set of changeset related to a push or a pull. The approach used to define "relevant" have been successfully tested in evolve for 6 months. diff --git a/mercurial/obsolete.py b/mercurial/obsolete.py --- a/mercurial/obsolete.py +++ b/mercurial/obsolete.py @@ -383,10 +383,37 @@ class obsstore(object): for p in parents: self.children.setdefault(p, set()).add(mark) if node.nullid in self.precursors: raise util.Abort(_('bad obsolescence marker detected: ' 'invalid successors nullid')) + def relevantmarkers(self, nodes): + """return a set of all obsolescence markers relevant to a set of node. + + "relevant" to a set of node mean: + + - marker that use this changeset as successors + - prune marker of direct children on this changeset. + - recursive application of the two rules on precursors of these markers + + It is a set so you cannot rely on order""" + pendingnodes = set(nodes) + seenmarkers = set() + seennodes = set(pendingnodes) + precursorsmarkers = self.precursors + children = self.children + while pendingnodes: + direct = set() + for current in pendingnodes: + direct.update(precursorsmarkers.get(current, ())) + pruned = [m for m in children.get(current, ()) if not m[1]] + direct.update(pruned) + direct -= seenmarkers + pendingnodes = set([m[0] for m in direct]) + seenmarkers |= direct + pendingnodes -= seennodes + seennodes |= pendingnodes + return seenmarkers def _encodemarkers(markers, addheader=False): # Kept separate from flushmarkers(), it will be reused for # markers exchange. if addheader: