# HG changeset patch # User Pierre-Yves David # Date 2014-10-03 04:28:18 # Node ID ef2c1ea8fb2cb75766498d8f772afd8e3e72d5a4 # Parent f40a57e8fda1c6290b8fb48effcf6275fb32296e addset: split simple and ordered iteration We have two goals here. First, we would like to restore the former iteration order we had in 2.9. Second, we want this logic to be reusable for `fastasc` and `fastdesc` methods. 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