From 9b224dd6949abab0c6e7bce187f981f78a0caee7 Mon Sep 17 00:00:00 2001 From: Pierre-Yves David Date: Tue, 19 Aug 2014 17:03:10 -0700 Subject: [PATCH] obsstore: add relevantmarkers method We add a ``relevantmarkers`` method to fetch all markers that seem relevant to a set of nodes. See function documentation about how this set is computed. This will let us exchange only the markers that seem "relevant" to the set of changesets related to a push or a pull. The approach used to define "relevant" has been successfully tested in evolve for 6 months. --- mercurial/obsolete.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/mercurial/obsolete.py b/mercurial/obsolete.py index 003453de8d..99b9fb49ec 100644 --- a/mercurial/obsolete.py +++ b/mercurial/obsolete.py @@ -385,6 +385,34 @@ class obsstore(object): 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 nodes. + + "relevant" to a set of nodes mean: + + - marker that use this changeset as successor + - 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