Skip to content
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

Update hashbrown to 0.15 #15801

Merged
merged 2 commits into from
Dec 10, 2024
Merged

Conversation

clarfonthey
Copy link
Contributor

@clarfonthey clarfonthey commented Oct 9, 2024

Updating dependencies; adopted version of #15696. (Supercedes #15696.)

Long answer: hashbrown is no longer using ahash by default, meaning that we can't use the default-hasher methods with ahasher. So, we have to use the longer-winded versions instead. This takes the opportunity to also switch our default hasher as well, but without actually enabling the default-hasher feature for hashbrown, meaning that we'll be able to change our hasher more easily at the cost of all of these method calls being obnoxious forever.

One large change from 0.15 is that insert_unique_unchecked is now unsafe, and for cases where unsafe code was denied at the crate level, I replaced it with insert.

Migration Guide

bevy_utils has updated its version of hashbrown to 0.15 and now defaults to foldhash instead of ahash. This means that if you've hard-coded your hasher to bevy_utils::AHasher or separately used the ahash crate in your code, you may need to switch to foldhash to ensure that everything works like it does in Bevy.

@clarfonthey clarfonthey force-pushed the hashbrown-0.15 branch 4 times, most recently from 1f86e6e to 89ccf19 Compare October 9, 2024 22:33
@alice-i-cecile alice-i-cecile added C-Dependencies A change to the crates that Bevy depends on A-Utils Utility functions and types S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Oct 9, 2024
@mnmaita
Copy link
Member

mnmaita commented Oct 10, 2024

@clarfonthey looks like there's a formatting issue somewhere, could you try running the formatter and push again?

@clarfonthey
Copy link
Contributor Author

Yeah, I was running into some difficulties fixing the lints but will try and fix this today or tomorrow.

@clarfonthey
Copy link
Contributor Author

Rereading the changelog, I misunderstood what hashbrown did and they actually switched to a better hash that we should probably use instead. Gonna probably find a way to factor that in.

@BenjaminBrienen BenjaminBrienen added S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Oct 12, 2024
@clarfonthey clarfonthey force-pushed the hashbrown-0.15 branch 4 times, most recently from 9e73303 to bba0dda Compare October 14, 2024 04:31
@@ -1422,8 +1422,11 @@ impl Bundles {
.or_insert_with(|| {
let (id, storages) =
initialize_dynamic_bundle(bundle_infos, components, Vec::from(component_ids));
self.dynamic_bundle_storages
.insert_unique_unchecked(id, storages);
// SAFETY: We know the ID is unique
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm adding this comment to appease the lint, but I actually don't know if we do know if the ID is unique.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I´ve checked the places where Bundles::init_dynamic_info was being used and most of them are internal facing, but I found EntityWorldMut::insert_by_ids, EntityWorldMut::retain and EntityWorldMut::clear which might be public facing I think?

HashMap::insert_unique_unchecked says:

    /// This operation is safe if a key does not exist in the map.
    ///
    /// However, if a key exists in the map already, the behavior is unspecified:
    /// this operation may panic, loop forever, or any following operation with the map
    /// may panic, loop forever or return arbitrary result.

So I'm unsure if we should say something like the caller ensures the uniqueness, and even add some notes in the EntityWorldMut methods if applicable? I guess I'm thinking out loud. 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, I'm honestly fine just changing this to insert and leaving it at that :p

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, so, I double-checked and the bundle ID is always increasing here, and without concurrency, we don't need to worry about data races. So, I updated the comment to clarify it is actually unique and leaving it.

@clarfonthey clarfonthey force-pushed the hashbrown-0.15 branch 4 times, most recently from 965855a to ed0e28a Compare October 14, 2024 04:51
@clarfonthey
Copy link
Contributor Author

This should be ready for review, modulo whatever tiny nitpicks CI throws at me.

Not sure if the migration guide is adequate: not sure how much we care about bevy_utils' public API, as far as like, whether people should be using it or not.

@hymm
Copy link
Contributor

hymm commented Oct 14, 2024

What is better about foldhash vs ahash? Is it really worth taking the extra dependency?

@BenjaminBrienen BenjaminBrienen added the D-Straightforward Simple bug fixes and API improvements, docs, test and examples label Oct 14, 2024
@clarfonthey
Copy link
Contributor Author

Final changes made:

  • Update "ID is unique" comment to actually clarify why ID is unique
  • Normalise let x: HashMap<_, _> = HashMap:: to let x = <HashMap<_, _>>:: and similarly for HashSet, to make things less verbose

@clarfonthey
Copy link
Contributor Author

(If someone could mark this as ready for final review, I'd appreciate it. I think this should qualify as ready.)

@bushrat011899 bushrat011899 added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Dec 8, 2024
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Dec 10, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Dec 10, 2024
@clarfonthey
Copy link
Contributor Author

(I'll try and take a look at the failures soon)

@clarfonthey
Copy link
Contributor Author

clarfonthey commented Dec 10, 2024

Ah, fun: the singular PR that got in the queue before this one didn't result in any merge conflicts, but it did add more uses of insert_unique_unchecked that now need unsafe blocks :(

Those have to be removed now, since bevy_reflect has deny(unsafe_code).

@clarfonthey
Copy link
Contributor Author

(Merge conflict should be resolved; ready to merge now.)

@BenjaminBrienen
Copy link
Contributor

.animated_1733845085550.gif

@clarfonthey
Copy link
Contributor Author

(kind of shocked that ci compile didn't catch that, tbh)

@clarfonthey
Copy link
Contributor Author

(Okay, this time I waited until CI passed. Should be ready to merge now. <3)

@alice-i-cecile alice-i-cecile added this pull request to the merge queue Dec 10, 2024
@alice-i-cecile
Copy link
Member

Thanks for shepherding this across the finish line <3

@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Dec 10, 2024
@clarfonthey
Copy link
Contributor Author

So, I had no idea about these patches that were being run in CI, but they seem pretty brittle-- it would be much better (IMHO) to use #[cfg] or cfg! to enable/disable these features than use patches, IMHO, so that at least they would be visible to people searching through the code. That said, I'll try and see what I can do.

@clarfonthey
Copy link
Contributor Author

I also have genuinely no idea why that patch failed on this PR. It appears to be referencing an earlier change where the patch should have broken, but it somehow did not trigger until now. And there were no recent changes to the CI job, either. It just makes absolutely no sense why this PR would be the one to trigger it, but at least, it did, and I fixed it.

@alice-i-cecile alice-i-cecile added this pull request to the merge queue Dec 10, 2024
Merged via the queue into bevyengine:main with commit 711246a Dec 10, 2024
31 of 32 checks passed
BD103 pushed a commit to BD103/bevy that referenced this pull request Dec 10, 2024
Updating dependencies; adopted version of bevyengine#15696. (Supercedes bevyengine#15696.)

Long answer: hashbrown is no longer using ahash by default, meaning that
we can't use the default-hasher methods with ahasher. So, we have to use
the longer-winded versions instead. This takes the opportunity to also
switch our default hasher as well, but without actually enabling the
default-hasher feature for hashbrown, meaning that we'll be able to
change our hasher more easily at the cost of all of these method calls
being obnoxious forever.

One large change from 0.15 is that `insert_unique_unchecked` is now
`unsafe`, and for cases where unsafe code was denied at the crate level,
I replaced it with `insert`.

## Migration Guide

`bevy_utils` has updated its version of `hashbrown` to 0.15 and now
defaults to `foldhash` instead of `ahash`. This means that if you've
hard-coded your hasher to `bevy_utils::AHasher` or separately used the
`ahash` crate in your code, you may need to switch to `foldhash` to
ensure that everything works like it does in Bevy.
@clarfonthey clarfonthey deleted the hashbrown-0.15 branch December 10, 2024 20:20
ecoskey pushed a commit to ecoskey/bevy that referenced this pull request Jan 6, 2025
Updating dependencies; adopted version of bevyengine#15696. (Supercedes bevyengine#15696.)

Long answer: hashbrown is no longer using ahash by default, meaning that
we can't use the default-hasher methods with ahasher. So, we have to use
the longer-winded versions instead. This takes the opportunity to also
switch our default hasher as well, but without actually enabling the
default-hasher feature for hashbrown, meaning that we'll be able to
change our hasher more easily at the cost of all of these method calls
being obnoxious forever.

One large change from 0.15 is that `insert_unique_unchecked` is now
`unsafe`, and for cases where unsafe code was denied at the crate level,
I replaced it with `insert`.

## Migration Guide

`bevy_utils` has updated its version of `hashbrown` to 0.15 and now
defaults to `foldhash` instead of `ahash`. This means that if you've
hard-coded your hasher to `bevy_utils::AHasher` or separately used the
`ahash` crate in your code, you may need to switch to `foldhash` to
ensure that everything works like it does in Bevy.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Utils Utility functions and types C-Dependencies A change to the crates that Bevy depends on D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants