-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Preserve insertion order in maps that are traversed #25218
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
Conversation
Consumers of an `Immutable{List,Map,Set}` cannot know whether it has been created from a source with unspecified iteration order, such as `HashMap`. Since `ImmutableMap` itself prescribes that it preserves insertion order, it's reasonable for consumers to expect a specified, reasonable, deterministic order. While the current implementation of `HashMap` in the OpenJDK still results in a deterministic order, this kind of "sequenced-washing" doesn't cause non-determinism, but it still runs the risk of having the order of elements change between JDK versions or vendors. The locations changed in this PR have been identified by instrumenting the factory methods of the `Immutable{List,Map,Set}` classes to track whether they 1) have been created from an unsequenced collection and 2) are iterated over. I then manually picked out those cases in which I couldn't rule out that a change in order would be observable to users. Related to google/guava#6903 (comment)
505a0a2
to
b45d5d4
Compare
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 general, I support this change and think this is worthwhile. However, I am worried about backsliding. What can we do to keep new uses of non-SequencedMap implementations from being added, or is this not a concern?
It's a real concern and a proper fix would likely require having |
I see, thanks. I looked at the linked Guava thread and it does look difficult. It looks like some of the current test failures are real, so I will hold off further review until those are addressed. |
18e0f63
to
74c4ac9
Compare
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.
LGTM! Thanks for doing this.
Though I wonder if sometimes what we need is an ImmutableMap
that semantically does not guarantee consistent iteration ordering, and then an ImmutableSequencedMap
that does. (Several places in this PR feel like they really want an immutable map but don't care about the order at all; but they have to "care" now because they're offering an ImmutableMap
.)
src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfigurationValue.java
Outdated
Show resolved
Hide resolved
…ildConfigurationValue.java Co-authored-by: Xùdōng Yáng <[email protected]>
That could be an alternative for Guava. A new class would also resolve the concerns around adopting |
While I see the logic (and the implementation could intentionally shuffle order to prevent people from depending on it!), I think it's unlikely that we'd do it. Inside Google, we have a JDK patch that shuffles the order of plain old That's seemed to hit a pretty good spot in the cost-benefit space. I can definitely see how the ability to actively request randomization could be useful, especially outside Google. But I figure:
|
@bazel-io flag |
@fmeum Can this go to 8.2.0? Or do we have to include it in 8.1.0? |
This can wait for 8.2.0 |
@bazel-io fork 8.2.0 |
Consumers of an `Immutable{List,Map,Set}` cannot know whether it has been created from a source with unspecified iteration order, such as `HashMap`. Since `ImmutableMap` itself prescribes that it preserves insertion order, it's reasonable for consumers to expect a specified, reasonable, deterministic order. While the current implementation of `HashMap` in the OpenJDK still results in a deterministic order, this kind of "sequenced-washing" doesn't cause non-determinism, but it still runs the risk of having the order of elements change between JDK versions or vendors. The locations changed in this PR have been identified by instrumenting the factory methods of the `Immutable{List,Map,Set}` classes to track whether they 1) have been created from an unsequenced collection and 2) are iterated over. I then manually picked out those cases in which I couldn't rule out that a change in order would be observable to users. Related to google/guava#6903 (comment) Closes bazelbuild#25218. PiperOrigin-RevId: 724341188 Change-Id: I2f38a4c3dad80055cb8d80853e9f211836019e5b
Consumers of an `Immutable{List,Map,Set}` cannot know whether it has been created from a source with unspecified iteration order, such as `HashMap`. Since `ImmutableMap` itself prescribes that it preserves insertion order, it's reasonable for consumers to expect a specified, reasonable, deterministic order. While the current implementation of `HashMap` in the OpenJDK still results in a deterministic order, this kind of "sequenced-washing" doesn't cause non-determinism, but it still runs the risk of having the order of elements change between JDK versions or vendors. The locations changed in this PR have been identified by instrumenting the factory methods of the `Immutable{List,Map,Set}` classes to track whether they 1) have been created from an unsequenced collection and 2) are iterated over. I then manually picked out those cases in which I couldn't rule out that a change in order would be observable to users. Related to google/guava#6903 (comment) Closes #25218. PiperOrigin-RevId: 724341188 Change-Id: I2f38a4c3dad80055cb8d80853e9f211836019e5b Commit b03cb63 Co-authored-by: Fabian Meumertzheim <[email protected]>
Consumers of an
Immutable{List,Map,Set}
cannot know whether it has been created from a source with unspecified iteration order, such asHashMap
. SinceImmutableMap
itself prescribes that it preserves insertion order, it's reasonable for consumers to expect a specified, reasonable, deterministic order. While the current implementation ofHashMap
in the OpenJDK still results in a deterministic order, this kind of "sequenced-washing" doesn't cause non-determinism, but it still runs the risk of having the order of elements change between JDK versions or vendors.The locations changed in this PR have been identified by instrumenting the factory methods of the
Immutable{List,Map,Set}
classes to track whether they 1) have been created from an unsequenced collection and 2) are iterated over. I then manually picked out those cases in which I couldn't rule out that a change in order would be observable to users.Related to google/guava#6903 (comment)