comparison mercurial/revset.py @ 25131:adfe4d9680bf

revset: extract addset._iterordered to free function It never uses self, so let's make it less dependent on variables.
author Yuya Nishihara <yuya@tcha.org>
date Sat, 16 May 2015 21:42:09 +0900
parents a94ef7f517e0
children 91c49621b2b8
comparison
equal deleted inserted replaced
25130:a94ef7f517e0 25131:adfe4d9680bf
2933 return None 2933 return None
2934 2934
2935 def __repr__(self): 2935 def __repr__(self):
2936 return '<%s %r>' % (type(self).__name__, self._subset) 2936 return '<%s %r>' % (type(self).__name__, self._subset)
2937 2937
2938 def _iterordered(ascending, iter1, iter2):
2939 """produce an ordered iteration from two iterators with the same order
2940
2941 The ascending is used to indicated the iteration direction.
2942 """
2943 choice = max
2944 if ascending:
2945 choice = min
2946
2947 val1 = None
2948 val2 = None
2949 try:
2950 # Consume both iterators in an ordered way until one is empty
2951 while True:
2952 if val1 is None:
2953 val1 = iter1.next()
2954 if val2 is None:
2955 val2 = iter2.next()
2956 next = choice(val1, val2)
2957 yield next
2958 if val1 == next:
2959 val1 = None
2960 if val2 == next:
2961 val2 = None
2962 except StopIteration:
2963 # Flush any remaining values and consume the other one
2964 it = iter2
2965 if val1 is not None:
2966 yield val1
2967 it = iter1
2968 elif val2 is not None:
2969 # might have been equality and both are empty
2970 yield val2
2971 for val in it:
2972 yield val
2973
2938 class addset(abstractsmartset): 2974 class addset(abstractsmartset):
2939 """Represent the addition of two sets 2975 """Represent the addition of two sets
2940 2976
2941 Wrapper structure for lazily adding two structures without losing much 2977 Wrapper structure for lazily adding two structures without losing much
2942 performance on the __contains__ method 2978 performance on the __contains__ method
3066 if iter2 is None: 3102 if iter2 is None:
3067 # let's avoid side effect (not sure it matters) 3103 # let's avoid side effect (not sure it matters)
3068 iter2 = iter(sorted(self._r2, reverse=not self._ascending)) 3104 iter2 = iter(sorted(self._r2, reverse=not self._ascending))
3069 else: 3105 else:
3070 iter2 = iter2() 3106 iter2 = iter2()
3071 return self._iterordered(self._ascending, iter1, iter2) 3107 return _iterordered(self._ascending, iter1, iter2)
3072 3108
3073 def _trysetasclist(self): 3109 def _trysetasclist(self):
3074 """populate the _asclist attribute if possible and necessary""" 3110 """populate the _asclist attribute if possible and necessary"""
3075 if self._genlist is not None and self._asclist is None: 3111 if self._genlist is not None and self._asclist is None:
3076 self._asclist = sorted(self._genlist) 3112 self._asclist = sorted(self._genlist)
3082 return self._asclist.__iter__ 3118 return self._asclist.__iter__
3083 iter1 = self._r1.fastasc 3119 iter1 = self._r1.fastasc
3084 iter2 = self._r2.fastasc 3120 iter2 = self._r2.fastasc
3085 if None in (iter1, iter2): 3121 if None in (iter1, iter2):
3086 return None 3122 return None
3087 return lambda: self._iterordered(True, iter1(), iter2()) 3123 return lambda: _iterordered(True, iter1(), iter2())
3088 3124
3089 @property 3125 @property
3090 def fastdesc(self): 3126 def fastdesc(self):
3091 self._trysetasclist() 3127 self._trysetasclist()
3092 if self._asclist is not None: 3128 if self._asclist is not None:
3093 return self._asclist.__reversed__ 3129 return self._asclist.__reversed__
3094 iter1 = self._r1.fastdesc 3130 iter1 = self._r1.fastdesc
3095 iter2 = self._r2.fastdesc 3131 iter2 = self._r2.fastdesc
3096 if None in (iter1, iter2): 3132 if None in (iter1, iter2):
3097 return None 3133 return None
3098 return lambda: self._iterordered(False, iter1(), iter2()) 3134 return lambda: _iterordered(False, iter1(), iter2())
3099
3100 def _iterordered(self, ascending, iter1, iter2):
3101 """produce an ordered iteration from two iterators with the same order
3102
3103 The ascending is used to indicated the iteration direction.
3104 """
3105 choice = max
3106 if ascending:
3107 choice = min
3108
3109 val1 = None
3110 val2 = None
3111 try:
3112 # Consume both iterators in an ordered way until one is
3113 # empty
3114 while True:
3115 if val1 is None:
3116 val1 = iter1.next()
3117 if val2 is None:
3118 val2 = iter2.next()
3119 next = choice(val1, val2)
3120 yield next
3121 if val1 == next:
3122 val1 = None
3123 if val2 == next:
3124 val2 = None
3125 except StopIteration:
3126 # Flush any remaining values and consume the other one
3127 it = iter2
3128 if val1 is not None:
3129 yield val1
3130 it = iter1
3131 elif val2 is not None:
3132 # might have been equality and both are empty
3133 yield val2
3134 for val in it:
3135 yield val
3136 3135
3137 def __contains__(self, x): 3136 def __contains__(self, x):
3138 return x in self._r1 or x in self._r2 3137 return x in self._r1 or x in self._r2
3139 3138
3140 def sort(self, reverse=False): 3139 def sort(self, reverse=False):