feat: Add iterator size hints#3552
Conversation
Coverage Report for CI Build 4245Coverage increased (+0.02%) to 94.637%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsNo coverage regressions found. Coverage Stats
💛 - Coveralls |
e72a1d3 to
605789e
Compare
605789e to
4c53b25
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4c53b2561f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0e021d96d0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5a3d8c8abd
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } | ||
| }) | ||
| }, | ||
| length=self.size, |
There was a problem hiding this comment.
Avoid advertising exact lengths for mutable hash maps
When a caller mutates the map after creating this iterator, the closure scans the current self.entries but the advertised length is the old self.size. For example, let it = map.iter(); map.clear(); leaves it.length() as the old nonzero size, and the first next() returns None with a positive exact length, tripping the new Iter::next debug assertion and misleading callers that use length() for preallocation; the same pattern applies to keys() and values().
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 99f8df93fb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } | ||
| }) | ||
| }, | ||
| size_hint=self.size, |
There was a problem hiding this comment.
Avoid exact hints on mutable sorted-map iterators
If a SortedMap is mutated after iter() is created but before it is consumed, set/remove update the AVL nodes in place, and this traversal starts from the captured root reference and can observe the changed tree. For example, creating an iterator over a one-entry map and then inserting a smaller key makes this iterator yield two entries while still advertising Some(1), so size_hint() underreports the remaining elements; the same pattern applies to the sibling key/value iterators that use self.size as an exact hint.
Useful? React with 👍 / 👎.
| } | ||
| }) | ||
| }, | ||
| size_hint=self.size, |
There was a problem hiding this comment.
Avoid exact hints on mutable sorted-set iterators
If a SortedSet is mutated after iter() is created but before it is consumed, add/remove mutate the captured node graph in place, so the iterator can traverse the changed tree while its exact hint remains the old self.size. For instance, creating an iterator over {2} and then adding 1 makes it yield both 1 and 2 while advertising Some(1), which makes size_hint() incorrect for callers that preallocate from it.
Useful? React with 👍 / 👎.
Design
The goal is to provide a size hint for iterators, which can help reduce allocations. Rust's
size_hintuses an always-present lower bound plus an optional upper bound which is rarely used. Here we take a different approach and introducesize_hint, an optional remaining-count hint. For example,mappreserves the hint, whilefilterdrops it because the output size is unknown.The hint is intended to be exact for trusted collection iterators and iterator adapters that can preserve that information, but it is still only a performance hint. User-provided hints are not treated as correctness invariants: negative hints are clamped to zero, consuming an iterator never drives the hint below zero, and an iterator ending early simply updates the hint to
Some(0).Summary
Iterand exposeIter::size_hintIter::newandIter2::newacceptsize_hint? : IntNon-goal
Mutating a collection while consuming one of its iterators remains unsupported. Captured bounds and
size_hintmetadata are only for keeping performance hints aligned with the traversal created at iterator construction; they do not make concurrent mutation supported.Validation
moon checkmoon fmtmoon infomoon testgit diff --check