# HG changeset patch # User Martijn Pieters # Date 1465898736 -3600 # Node ID 38e0c83c7ee4381b0e2106356e09ba10413092ce # Parent 62b890496de5dc6b64febc2aebc9f5caeadb9201 revset: record if a set is in topographical order A later revision adds actual topographical sorting. Recording if a set is in this order allows hg log -G to avoid re-sorting the revset. diff -r 62b890496de5 -r 38e0c83c7ee4 mercurial/cmdutil.py --- a/mercurial/cmdutil.py Mon Jun 13 21:30:14 2016 +0100 +++ b/mercurial/cmdutil.py Tue Jun 14 11:05:36 2016 +0100 @@ -2147,7 +2147,7 @@ if opts.get('rev'): # User-specified revs might be unsorted, but don't sort before # _makelogrevset because it might depend on the order of revs - if not revs.isdescending(): + if not (revs.isdescending() or revs.istopo()): revs.sort(reverse=True) if expr: # Revset matchers often operate faster on revisions in changelog diff -r 62b890496de5 -r 38e0c83c7ee4 mercurial/revset.py --- a/mercurial/revset.py Mon Jun 13 21:30:14 2016 +0100 +++ b/mercurial/revset.py Tue Jun 14 11:05:36 2016 +0100 @@ -2508,6 +2508,10 @@ """True if the set will iterate in descending order""" raise NotImplementedError() + def istopo(self): + """True if the set will iterate in topographical order""" + raise NotImplementedError() + @util.cachefunc def min(self): """return the minimum element in the set""" @@ -2593,12 +2597,13 @@ Every method in this class should be implemented by any smartset class. """ - def __init__(self, data=(), datarepr=None): + def __init__(self, data=(), datarepr=None, istopo=False): """ datarepr: a tuple of (format, obj, ...), a function or an object that provides a printable representation of the given data. """ self._ascending = None + self._istopo = istopo if not isinstance(data, list): if isinstance(data, set): self._set = data @@ -2641,12 +2646,14 @@ def sort(self, reverse=False): self._ascending = not bool(reverse) + self._istopo = False def reverse(self): if self._ascending is None: self._list.reverse() else: self._ascending = not self._ascending + self._istopo = False def __len__(self): return len(self._list) @@ -2667,6 +2674,14 @@ return True return self._ascending is not None and not self._ascending + def istopo(self): + """Is the collection is in topographical order or not. + + This is part of the mandatory API for smartset.""" + if len(self) <= 1: + return True + return self._istopo + def first(self): if self: if self._ascending is None: @@ -2782,6 +2797,9 @@ def isdescending(self): return self._subset.isdescending() + def istopo(self): + return self._subset.istopo() + def first(self): for x in self: return x @@ -3028,6 +3046,12 @@ def isdescending(self): return self._ascending is not None and not self._ascending + def istopo(self): + # not worth the trouble asserting if the two sets combined are still + # in topographical order. Use the sort() predicate to explicitly sort + # again instead. + return False + def reverse(self): if self._ascending is None: self._list.reverse() @@ -3195,6 +3219,12 @@ def isdescending(self): return not self._ascending + def istopo(self): + # not worth the trouble asserting if the two sets combined are still + # in topographical order. Use the sort() predicate to explicitly sort + # again instead. + return False + def first(self): if self._ascending: it = self.fastasc @@ -3257,6 +3287,12 @@ def reverse(self): self._ascending = not self._ascending + def istopo(self): + # not worth the trouble asserting if the two sets combined are still + # in topographical order. Use the sort() predicate to explicitly sort + # again instead. + return False + def _iterfilter(self, iterrange): s = self._hiddenrevs for r in iterrange: