##// END OF EJS Templates
revset: fix iteration over ordered addset composed of non-ordered operands...
Pierre-Yves David -
r25115:5548f558 default
parent child Browse files
Show More
@@ -2974,10 +2974,10 b' class addset(abstractsmartset):'
2974 >>> [x for x in rs], [x for x in rs.fastasc()] # without _asclist
2974 >>> [x for x in rs], [x for x in rs.fastasc()] # without _asclist
2975 ([0, 2, 3, 4, 5], [0, 2, 3, 4, 5])
2975 ([0, 2, 3, 4, 5], [0, 2, 3, 4, 5])
2976 >>> assert not rs._asclist
2976 >>> assert not rs._asclist
2977 >>> len(rs) # BROKEN
2977 >>> len(rs)
2978 6
2978 5
2979 >>> [x for x in rs], [x for x in rs.fastasc()] # BROKEN with _asclist
2979 >>> [x for x in rs], [x for x in rs.fastasc()]
2980 ([0, 2, 2, 3, 4, 5], [0, 2, 2, 3, 4, 5])
2980 ([0, 2, 3, 4, 5], [0, 2, 3, 4, 5])
2981 >>> assert rs._asclist
2981 >>> assert rs._asclist
2982
2982
2983 iterate descending:
2983 iterate descending:
@@ -2985,23 +2985,23 b' class addset(abstractsmartset):'
2985 >>> [x for x in rs], [x for x in rs.fastdesc()] # without _asclist
2985 >>> [x for x in rs], [x for x in rs.fastdesc()] # without _asclist
2986 ([5, 4, 3, 2, 0], [5, 4, 3, 2, 0])
2986 ([5, 4, 3, 2, 0], [5, 4, 3, 2, 0])
2987 >>> assert not rs._asclist
2987 >>> assert not rs._asclist
2988 >>> len(rs) # BROKEN
2988 >>> len(rs)
2989 6
2989 5
2990 >>> [x for x in rs], [x for x in rs.fastdesc()] # BROKEN with _asclist
2990 >>> [x for x in rs], [x for x in rs.fastdesc()]
2991 ([5, 4, 3, 2, 2, 0], [5, 4, 3, 2, 2, 0])
2991 ([5, 4, 3, 2, 0], [5, 4, 3, 2, 0])
2992 >>> assert rs._asclist
2992 >>> assert rs._asclist
2993
2993
2994 iterate ascending without fastasc:
2994 iterate ascending without fastasc:
2995 >>> rs = addset(xs, generatorset(ys), ascending=True)
2995 >>> rs = addset(xs, generatorset(ys), ascending=True)
2996 >>> assert rs.fastasc is None
2996 >>> assert rs.fastasc is None
2997 >>> [x for x in rs] # BROKEN
2997 >>> [x for x in rs]
2998 [0, 2, 2, 3, 4, 5]
2998 [0, 2, 3, 4, 5]
2999
2999
3000 iterate descending without fastdesc:
3000 iterate descending without fastdesc:
3001 >>> rs = addset(generatorset(xs), ys, ascending=False)
3001 >>> rs = addset(generatorset(xs), ys, ascending=False)
3002 >>> assert rs.fastdesc is None
3002 >>> assert rs.fastdesc is None
3003 >>> [x for x in rs] # BROKEN
3003 >>> [x for x in rs]
3004 [5, 4, 3, 2, 2, 0]
3004 [5, 4, 3, 2, 0]
3005 """
3005 """
3006 def __init__(self, revs1, revs2, ascending=None):
3006 def __init__(self, revs1, revs2, ascending=None):
3007 self._r1 = revs1
3007 self._r1 = revs1
@@ -3020,10 +3020,10 b' class addset(abstractsmartset):'
3020 @util.propertycache
3020 @util.propertycache
3021 def _list(self):
3021 def _list(self):
3022 if not self._genlist:
3022 if not self._genlist:
3023 self._genlist = baseset(self._iterator())
3023 self._genlist = baseset(iter(self))
3024 return self._genlist
3024 return self._genlist
3025
3025
3026 def _iterator(self):
3026 def __iter__(self):
3027 """Iterate over both collections without repeating elements
3027 """Iterate over both collections without repeating elements
3028
3028
3029 If the ascending attribute is not set, iterate over the first one and
3029 If the ascending attribute is not set, iterate over the first one and
@@ -3034,35 +3034,43 b' class addset(abstractsmartset):'
3034 same time, yielding only one value at a time in the given order.
3034 same time, yielding only one value at a time in the given order.
3035 """
3035 """
3036 if self._ascending is None:
3036 if self._ascending is None:
3037 def gen():
3037 if self._genlist:
3038 return iter(self._genlist)
3039 def arbitraryordergen():
3038 for r in self._r1:
3040 for r in self._r1:
3039 yield r
3041 yield r
3040 inr1 = self._r1.__contains__
3042 inr1 = self._r1.__contains__
3041 for r in self._r2:
3043 for r in self._r2:
3042 if not inr1(r):
3044 if not inr1(r):
3043 yield r
3045 yield r
3044 gen = gen()
3046 return arbitraryordergen()
3045 else:
3047 # try to use our own fast iterator if it exists
3046 iter1 = iter(self._r1)
3047 iter2 = iter(self._r2)
3048 gen = self._iterordered(self._ascending, iter1, iter2)
3049 return gen
3050
3051 def __iter__(self):
3052 if self._ascending is None:
3053 if self._genlist:
3054 return iter(self._genlist)
3055 return iter(self._iterator())
3056 self._trysetasclist()
3048 self._trysetasclist()
3057 if self._ascending:
3049 if self._ascending:
3058 it = self.fastasc
3050 it = self.fastasc
3059 else:
3051 else:
3060 it = self.fastdesc
3052 it = self.fastdesc
3061 if it is None:
3053 if it is not None:
3062 # consume the gen and try again
3054 return it()
3063 self._list
3055 # maybe half of the component supports fast
3064 return iter(self)
3056 attr = 'fastdesc'
3065 return it()
3057 if self._ascending:
3058 attr = 'fastasc'
3059 # get iterator for _r1
3060 iter1 = getattr(self._r1, attr)
3061 if iter1 is None:
3062 # let's avoid side effect (not sure it matters)
3063 iter1 = iter(sorted(self._r1, reverse=not self._ascending))
3064 else:
3065 iter1 = iter1()
3066 # get iterator for _r2
3067 iter2 = getattr(self._r2, attr)
3068 if iter2 is None:
3069 # let's avoid side effect (not sure it matters)
3070 iter2 = iter(sorted(self._r2, reverse=not self._ascending))
3071 else:
3072 iter2 = iter2()
3073 return self._iterordered(self._ascending, iter1, iter2)
3066
3074
3067 def _trysetasclist(self):
3075 def _trysetasclist(self):
3068 """populate the _asclist attribute if possible and necessary"""
3076 """populate the _asclist attribute if possible and necessary"""
General Comments 0
You need to be logged in to leave comments. Login now