-
Notifications
You must be signed in to change notification settings - Fork 12.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
Tracking Issue for map_many_mut #97601
Comments
Would it be better for this to return |
I don't think so, returning a |
Sure, but the current implementation makes things more difficult for people who want to do multiple lookups in parallel and then do some mutations based on which keys exist and don't exist. Returning If I follow the history correctly, the libstd implementation returns |
Use get_many_mut to reduce the cost of setting up check cfg values This PR use the newly added [`get_many_mut`](rust-lang#97601) function in [`HashMap`](https://doc.rust-lang.org/nightly/std/collections/hash_map/struct.HashMap.html#method.get_many_mut) to reduce the cost of setting up the initial check cfg values. cc `@petrochenkov`
Bikesheddy note: this is very similar to the notion of a "gather" (a la |
This seems very restrictive on the number of elements at the same time. Would be nice to have a version that supports Vec or Iterator of some sort. We don't have to support the general form now, but should think about how to design the API that adding general form is easy. |
Are there any performance benefits to this other than eliminating a for loop caller-side? Can someone explain the motivation or a use-case for this, given that the code this replaces is rather short and to-the-point? |
@mqudsi It's currently impossible in safe code to get simultaneous mutable references to different values in a |
What about BTreeMap ? Would it be possible to have |
Can it be done at all? |
Rather than returning references to values, could this be an entry-based API instead? That would forgo the questions about people wanting to potentially make multiple lookups without them necessarily failing if some of them are missing. The current proposed function could easily be built on top of an entry-based API, but vice-versa is not possible. |
Does it work to have multiple |
Store programs in a `hashbrown::HashMap` and expose `get_many_mut`. We can revisit this dependency when rust-lang/rust#97601 is resolved.
I implemented a similar thing in this pull request: rust-lang/hashbrown#408 |
I don't see how that does what was requested. As far as I can tell based on that PR, your changes still require a |
I assume they are waiting for this to reach stable for HashMaps before bringing it to BTreeMap. But if you just want something that works https://github.com/DrAlta/rust_quality_of_life.git implements .get_many_mut() for BTreeMap in the GetManyMut trait Thou it doesn't go poking around the innards of the BTreeMap it just iters over it and returns the wanted bits. |
We just had a very long conversation about this in today's @rust-lang/libs-api method. The outcome of that discussion was that we'd like to change the signatures to:
The two changes here are 1) panicking on duplicate indexes and 2) returning an array of Option rather than an Option of array. Our rationales for both of these are based on an expected usage model of either having an array of N keys that are statically known at compile time or having an array of most commonly 2 or perhaps 3 keys that are dynamically supplied by the user. Rationale for 1: In the static case you know there aren't duplicates, and in the dynamic case you have few enough items that you can easily Rationale for 2: In the dynamic case, we expect the common case to be 2 keys, and it's extremely easy to |
Change signature of `get_many_mut` APIs This PR changes the signature and contract of the `get_many_mut` APIs by 1. panicking on overlapping keys 2. returning an array of Option rather than an Option of array. This was asked by T-libs-api in rust-lang/rust#97601 (comment) regarding the corresponding std `HashMap` functions.
…heemdev Add `[Option<T>; N]::transpose` This PR as a new unstable libs API, `[Option<T>; N]::transpose`, which permits going from `[Option<T>; N]` to `Option<[T; N]>`. This new API doesn't have an ACP as it was directly asked by T-libs-api in rust-lang#97601 (comment): > [..] but it'd be trivial to provide a helper method `.transpose()` that turns array-of-Option into Option-of-array (**and we think that method should exist**; it already does for array-of-MaybeUninit). r? libs
Going to work on a PR to update this API to match the recent changes, since it's blocking another PR of mine. |
Add `[Option<T>; N]::transpose` This PR as a new unstable libs API, `[Option<T>; N]::transpose`, which permits going from `[Option<T>; N]` to `Option<[T; N]>`. This new API doesn't have an ACP as it was directly asked by T-libs-api in rust-lang/rust#97601 (comment): > [..] but it'd be trivial to provide a helper method `.transpose()` that turns array-of-Option into Option-of-array (**and we think that method should exist**; it already does for array-of-MaybeUninit). r? libs
Add `[Option<T>; N]::transpose` This PR as a new unstable libs API, `[Option<T>; N]::transpose`, which permits going from `[Option<T>; N]` to `Option<[T; N]>`. This new API doesn't have an ACP as it was directly asked by T-libs-api in rust-lang/rust#97601 (comment): > [..] but it'd be trivial to provide a helper method `.transpose()` that turns array-of-Option into Option-of-array (**and we think that method should exist**; it already does for array-of-MaybeUninit). r? libs
Just to make sure the consistency issue is |
Now that the unresolved questions have been resolved thanks to #97601 (comment), I would like to propose to stabilize this feature. Stabilization ReportImplementation History
API Surface// in HashMap
/// Attempts to get mutable references to `N` values in the map at once.
/// Panics if the same index was passed more than once.
pub fn get_many_mut<Q: ?Sized, const N: usize>(
&mut self,
ks: [&Q; N]
) -> [Option<&'_ mut V>; N]
where
K: Borrow<Q>,
Q: Hash + Eq + ?Sized;
/// UB if the same index was passed more than once.
pub unsafe fn get_many_unchecked_mut<Q: ?Sized, const N: usize>(
&mut self,
ks: [&Q; N],
) -> [Option<&'_ mut V>; N]
where
K: Borrow<Q>,
Q: Hash + Eq + ?Sized; Experience ReportThe compiler has been happily using Example Usages
cc @rust-lang/libs-api |
@rfcbot merge |
Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members: Concerns:
Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
I'd like to stabilize this at the same time as the slice version in case any API issues come up in either of them. @rfcbot concern stabilize-with-slice |
Feature gate:
#![feature(map_many_mut)]
This is a tracking issue for the
HashMap::get_many{,_unchecked}_mut
functions.Attempts to get mutable references to
N
values in the map at once.Public API
Steps / History
get_many_mut
andget_many_unchecked_mut
to HashMap #94647 and Change signature ofget_many_mut
APIs hashbrown#562Unresolved Questions
Should the return type be insteadResult<[Option<&mut V>; N], DuplicateKeys>
? Tracking Issue for map_many_mut #97601 (comment) and Tracking Issue for map_many_mut #97601 (comment)Tracking Issue for map_many_mut #97601 (comment)
Having instead a entry-like API? Tracking Issue for map_many_mut #97601 (comment)Tracking Issue for map_many_mut #97601 (comment)
The text was updated successfully, but these errors were encountered: