Mercurial > hg
changeset 20722:6894223ebc38
revset: changed _iterator() method on addset to work with a given order
If the two collections are in ascending order, yield their values in an
ordered way by iterating both at the same time and picking the values to
yield.
author | Lucas Moscovicz <lmoscovicz@fb.com> |
---|---|
date | Thu, 13 Mar 2014 13:29:04 -0700 |
parents | d642f176df52 |
children | fb9852c46a42 |
files | mercurial/revset.py |
diffstat | 1 files changed, 51 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/revset.py Thu Mar 13 14:51:04 2014 -0700 +++ b/mercurial/revset.py Thu Mar 13 13:29:04 2014 -0700 @@ -2340,14 +2340,60 @@ return self._genlist def _iterator(self): + """Iterate over both collections without repeating elements + + If the ascending attribute is not set, iterate over the first one and + then over the second one checking for membership on the first one so we + dont yield any duplicates. + + If the ascending attribute is set, iterate over both collections at the + same time, yielding only one value at a time in the given order. + """ if not self._iter: def gen(): - for r in self._r1: - yield r - s = self._r1.set() - for r in self._r2: - if r not in s: + if self._ascending is None: + 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()) return self._iter