Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Basic
This pull requests attempts to optimise the
iterate
method.In this scenario, exactly 130 values are requested from the list payments endpoint, as the implementation correctly guesses that any additional values would be "wasted":
In this scenario, a single request does not satisfy the demand. The Mollie API does not return pages of over 250 values. Therefore, the implementation requests two pages with 150 values each, rather than requesting 250 values twice "wasting" 200 values in the process:
Advanced
The
iterate
methods now return a lazy iterator: a container which creates and holds an upstream iterator when it is needed. As such, the implementation can watch for calls totake
,drop
, andfilter
and use that information to make an educated guess about the number of values which are to be consumed when the upstream iterator is created.A demand of infinity is initially guessed. The chain is then traversed from right to left:
take
reduces the guess to the lowest value out of the current guess and the limit passed totake
.drop
increases the guess by the limit passed todrop
.filter
resets the guess to infinity.Limitations
Limits applied through other means than
take
cannot be detected. The implementation does not optimise the following snippet:Because there is no way to predict how many values will satisfy a certain filter,
filter
beforetake
is not optimised:filter
aftertake
is OK, of course.Because any number of new iterators can be created from any iterator (through
drop
,filter
,map
, andtake
), those iterators together form a (rooted) tree. The educated guess is derived from the path between the root and the leaf which triggers the creation of the upstream iterator.This does mean that in the following example, this class incorrectly guesses that only 10 values are required when in actuality 12 are required: