def _sortedIterator(self, iterator, limit, orderBy, descending): exceeded = False if orderBy or descending: sortingKey = self._sortingKeys.get(orderBy) if self._toDT and self._fromDT and self._toDT - self._fromDT <= self.FULL_SORTING_TIMEFRAME: # If the timeframe is not too big we sort the whole dataset and limit it afterwards. Ths results in # better results but worse performance. limitedIterable = self._limitIterator( sorted(iterator, key=sortingKey, reverse=descending), limit) else: try: limitedIterable = sorted(self._limitIterator( iterator, limit), key=sortingKey, reverse=descending) except LimitExceededException: exceeded = True limitedIterable = sorted(self._intermediateResults, key=sortingKey, reverse=descending) else: limitedIterable = self._limitIterator(iterator, limit) # iterate over result for obj in limitedIterable: yield obj # in case the limit was exceeded while sorting the results, # raise the exception as if we were truly consuming an iterator if orderBy and exceeded: raise LimitExceededException()
def _limitIterator(self, iterator, limit): counter = 0 # this set acts as a checklist to know if a record has already been sent exclude = set() self._intermediateResults = [] for obj in iterator: if counter >= limit: raise LimitExceededException() if obj not in exclude and (not hasattr(obj, 'canAccess') or obj.canAccess(self._aw)): self._intermediateResults.append(obj) yield obj exclude.add(obj) counter += 1