diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -2638,52 +2638,20 @@ class _addset(_orderedsetmixin): same time, yielding only one value at a time in the given order. """ if not self._iter: - def gen(): - if self._ascending is None: + if self._ascending is None: + def gen(): for r in self._r1: yield r s = self._r1.set() for r in self._r2: if r not in s: yield r - else: - iter1 = iter(self._r1) - iter2 = iter(self._r2) - - val1 = None - val2 = None - - choice = max - if self._ascending: - choice = min - try: - # Consume both iterators in an ordered way until one is - # empty - while True: - if val1 is None: - val1 = iter1.next() - if val2 is None: - val2 = iter2.next() - next = choice(val1, val2) - yield next - if val1 == next: - val1 = None - if val2 == next: - val2 = None - except StopIteration: - # Flush any remaining values and consume the other one - it = iter2 - if val1 is not None: - yield val1 - it = iter1 - elif val2 is not None: - # might have been equality and both are empty - yield val2 - for val in it: - yield val - - self._iter = _generatorset(gen()) - + gen = gen() + else: + iter1 = iter(self._r1) + iter2 = iter(self._r2) + gen = self._iterordered(self._ascending, iter1, iter2) + self._iter = _generatorset(gen) return self._iter def __iter__(self): @@ -2691,6 +2659,47 @@ class _addset(_orderedsetmixin): return iter(self._genlist) return iter(self._iterator()) + def _iterordered(self, ascending, iter1, iter2): + """produce an ordered iteration from two iterators with the same order + + The ascending is used to indicated the iteration direction. + """ + choice = max + if ascending: + choice = min + + val1 = None + val2 = None + + choice = max + if self._ascending: + choice = min + try: + # Consume both iterators in an ordered way until one is + # empty + while True: + if val1 is None: + val1 = iter1.next() + if val2 is None: + val2 = iter2.next() + next = choice(val1, val2) + yield next + if val1 == next: + val1 = None + if val2 == next: + val2 = None + except StopIteration: + # Flush any remaining values and consume the other one + it = iter2 + if val1 is not None: + yield val1 + it = iter1 + elif val2 is not None: + # might have been equality and both are empty + yield val2 + for val in it: + yield val + def __contains__(self, x): return x in self._r1 or x in self._r2