-
Notifications
You must be signed in to change notification settings - Fork 5.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
6323374: (coll) Optimize Collections.unmodifiable* and synchronized* #2596
Conversation
👋 Welcome back igraves! A progress list of the required criteria for merging this PR into |
/csr |
@igraves this pull request will not be integrated until the CSR request JDK-8261677 for issue JDK-6323374 has been approved. |
Webrevs
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a space after if
-> if
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In addition year for license of Collections.java needs an update too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me.
Is there any behavior change here that merits a CSR review? |
Maybe. The one observable change is that calling |
Yes. The CSR was to consider primarily this case. Probably out of an abundance of caution here. @stuart-marks may have another case to consider. |
Yes. See my comments in the bug report: There is not only the issue of the identity of the object returned, but the change is also observable in the serialized form. Most people would consider the change (less nesting) to be an improvement, but the change is observable, and as we know any observable behavior can become depended upon by applications. |
Code changes all look good. I'm thinking that we should add The test seems to have a lot of uncomfortable dependencies, both explicit and implicit, on the various ImmutableCollection and UnmodifiableX implementation classes. Would it be sufficient to test various instances for reference equality and inequality instead? For example, something like
This would avoid having to write test cases that cover various internal classes. The ImmutableCollections classes have been reorganized in the past, and while we don't have any plans to do so again at the moment, there is always the possibility of it happening again. One could write out all the different cases "by hand" but there are rather a lot of them. It might be fruitful to extract the "wrap once, wrap again, assertNotSame, assertSame" logic into a generic test and drive it somehow with a data provider that provides the base instance and a wrapper function. |
Per @stuart-marks I rewrote the tests using some of his suggestions, which substantially reduced dependencies and test size. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The @implNote
additions are good, and the test rewrite looks good too.
* @param <T> the class of the objects in the set | ||
* @param s the sorted set for which an unmodifiable view is to be | ||
* returned. | ||
* @return an unmodifiable view of the specified sorted set. | ||
*/ | ||
public static <T> SortedSet<T> unmodifiableSortedSet(SortedSet<T> s) { | ||
if (s.getClass() == UnmodifiableSortedSet.class) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should a check like this also included "|| == UnmodifiableNavigableSet.class" or was there an explicit decision that the cost/benefit is not worthwhile, unlike in the case of unmodifiableList below?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good point. The case of unmodifiableList is such because the method can return two different classes depending the nature of the argument. I feel as though if we made this change here, we should consider doing the same check for vanilla unmodifiableSet to ensure it, too, doesn't wrap its subclasses. I'm amenable to this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To the second part of the question, there was no explicit cost/benefit analysis RE List or this case.
@igraves This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 331 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. As you do not have Committer status in this project an existing Committer must agree to sponsor your change. Possible candidates are the reviewers of this PR (@RogerRiggs, @cl4es, @stuart-marks, @jddarcy) but any other Committer may sponsor as well. ➡️ To flag this PR as ready for integration with the above commit message, type |
Hm. I had thought of this previously but I was a bit suspicious, and it didn't seem like it would make much difference, so I didn't say anything. But thinking about this further, the following issues arose:
this compiles without warnings, but it results in ClassCastException. The culprit is the new upcast that potentially allows In any case, the extra checking in the unmodifiableSortedSet and -Map methods needs to be taken out. Offhand I don't know if there's a similar issue between unmodifiableSortedSet and a NavigableSet (resp., Map), but on general principle I'd say to take it out too. It's likely not buying much anyway. The UnmodifiableList and UnmodifiableRandomAccessList stuff should stay, since that's how the RandomAccess marker interface is preserved. |
Good thought on the heap pollution. I had only been considering point 1. I was thinking that perhaps if we could catch some of the wrapping of subclasses we might be able to guard against situations where rewrapping could occur if we were interleaving calls between subclass and superclass wrapper methods. That seems like a bit of a reach and in light of your point about heap pollution I think it makes sense to walk back the changes and stay with the original. Likewise agree on the point about Lists. |
This reverts commit dda174c.
If the checks for Navigable set and the like are omitted, I'd prefer to a comment in the sources noting this is intention as a Navigable set is-a Sorted set. |
Added comments to the relevant methods noting our intention not to check for subclasses with a little note why. |
/integrate |
/sponsor |
@stuart-marks @igraves Since your change was applied there have been 331 commits pushed to the
Your commit was automatically rebased without conflicts. Pushed as commit dbef0ec. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
Modify the
unmodifiable*
methods injava.util.Collections
to be idempotent. That is, when given an immutable collection fromjava.util.ImmutableCollections
orjava.util.Collections
, these methods will return the reference instead of creating a new immutable collection that wraps the existing one.Progress
Issue
Reviewers
Download
$ git fetch https://git.openjdk.java.net/jdk pull/2596/head:pull/2596
$ git checkout pull/2596