##// END OF EJS Templates
lazyancestors: reuse __iter__ implementation in __contains__...
Martin von Zweigbergk -
r39518:77a2f6d8 default
parent child Browse files
Show More
@@ -308,18 +308,11 b' class lazyancestors(object):'
308 308 self._stoprev = stoprev
309 309 self._inclusive = inclusive
310 310
311 # Initialize data structures for __contains__.
312 # For __contains__, we use a heap rather than a deque because
313 # (a) it minimizes the number of parentrevs calls made
314 # (b) it makes the loop termination condition obvious
315 # Python's heap is a min-heap. Multiply all values by -1 to convert it
316 # into a max-heap.
317 self._containsvisit = [-rev for rev in revs]
318 heapq.heapify(self._containsvisit)
319 if inclusive:
320 self._containsseen = set(revs)
321 else:
322 self._containsseen = set()
311 self._containsseen = set()
312 self._containsiter = _lazyancestorsiter(self._parentrevs,
313 self._initrevs,
314 self._stoprev,
315 self._inclusive)
323 316
324 317 def __nonzero__(self):
325 318 """False if the set is empty, True otherwise."""
@@ -348,35 +341,29 b' class lazyancestors(object):'
348 341
349 342 def __contains__(self, target):
350 343 """Test whether target is an ancestor of self._initrevs."""
351 # Trying to do both __iter__ and __contains__ using the same visit
352 # heap and seen set is complex enough that it slows down both. Keep
353 # them separate.
354 344 seen = self._containsseen
355 345 if target in seen:
356 346 return True
347 iter = self._containsiter
348 if iter is None:
349 # Iterator exhausted
350 return False
357 351 # Only integer target is valid, but some callers expect 'None in self'
358 352 # to be False. So we explicitly allow it.
359 353 if target is None:
360 354 return False
361 355
362 parentrevs = self._parentrevs
363 visit = self._containsvisit
364 stoprev = self._stoprev
365 heappop = heapq.heappop
366 heappush = heapq.heappush
367 356 see = seen.add
368
369 targetseen = False
370
371 while visit and -visit[0] > target and not targetseen:
372 for parent in parentrevs(-heappop(visit)):
373 if parent < stoprev or parent in seen:
374 continue
375 # We need to make sure we push all parents into the heap so
376 # that we leave it in a consistent state for future calls.
377 heappush(visit, -parent)
378 see(parent)
379 if parent == target:
380 targetseen = True
381
382 return targetseen
357 try:
358 while True:
359 rev = next(iter)
360 see(rev)
361 if rev == target:
362 return True
363 if rev < target:
364 return False
365 except StopIteration:
366 # Set to None to indicate fast-path can be used next time, and to
367 # free up memory.
368 self._containsiter = None
369 return False
General Comments 0
You need to be logged in to leave comments. Login now