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

BTreeMap: clean up access to MaybeUninit arrays #79520

Merged
merged 1 commit into from
Dec 26, 2020

Conversation

ssomers
Copy link
Contributor

@ssomers ssomers commented Nov 28, 2020

Stop exposing and using immutable access to MaybeUninit slices when we need and have exclusive access to the tree.

r? @Mark-Simulacrum

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 28, 2020
@ssomers

This comment has been minimized.

unsafe fn edge_area(self) -> &'a [MaybeUninit<BoxedNode<K, V>>] {
Self::as_internal(&self).edges.as_slice()
unsafe fn edge_area(mut self) -> &'a [MaybeUninit<BoxedNode<K, V>>] {
Self::as_internal_mut(&mut self).edges.as_slice()
Copy link
Member

Choose a reason for hiding this comment

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

It seems quite odd to require unique access to get a read-only slice of the edges -- can you say more about the use case here?

Copy link
Contributor Author

@ssomers ssomers Dec 9, 2020

Choose a reason for hiding this comment

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

The change is not to require unique access (to the tree), we admit that the caller has it and needs to have it. We don't get you a slice of edges, but a slice of containers of edges. If you only have shared access to the tree, the only thing you could ever do with those containers is to read the initialized ones, and we already have better methods for that.

The actual use case is to unify the various methods that access MaybeUninits in another PR.

@Mark-Simulacrum
Copy link
Member

stop using immutable access when we have exclusive access to the tree

Why is this good? It feels like we should not impose exclusive access just to reborrow into a shared reference?

@ssomers
Copy link
Contributor Author

ssomers commented Dec 9, 2020

Why is this good? It feels like we should not impose exclusive access just to reborrow into a shared reference?

I've returned a &'a mut [_] instead now. #79347 merges the different methods to access MaybeUninit slices and then it always returns exclusiveness.

/// Exposes the entire key storage area in the node,
/// regardless of the node's current length,
/// having exclusive access to the entire node.
unsafe fn key_area(self) -> &'a [MaybeUninit<K>] {
Self::as_leaf(&self).keys.as_slice()
unsafe fn key_area(mut self) -> &'a mut [MaybeUninit<K>] {
Copy link
Member

Choose a reason for hiding this comment

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

Ok, so I was initially confused by this change -- it still seems unnecessary, as this PR doesn't introduce any cases where key_area is being used with the unique access being provided here. Since this PR is an attempt to split off part of #79347, I took a look there, and it looks like the change this is maybe.. not going far enough?

Can we include the next step of this refactor (but avoid the other changes)? I would expect, I guess, a PR that just switches away from using the different key_area/into_key_area etc methods to a single one, but doesn't do anything else (no introduction of e.g. slice_move). That would make it easier to judge whether the generics and such suggested in the other PR are worth it to me. As-is, it's hard to determine what the outcome is looking like quite yet.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it still seems unnecessary, as this PR doesn't introduce any cases where key_area is being used with the unique access being provided here

The compiler doesn't notice, but I think the uniqueness is being used and required. You cannot sensibly copy a MaybeUninit<K> if there might be someone else copying it too, because the key would be duplicated. The callers of key_area move ownership, so they need uniqueness, even though the ptr::copy doing the hard work for them doesn't care about the uniqueness of the source .

Can we include the next step of this refactor (but avoid the other changes)?

Not sure which next step and other changes you mean.

As-is, it's hard to determine what the outcome is looking like quite yet.

Again, not sure which outcome you mean. In my mind, the outcome looks a lot like #79347 (just needs rebase for the last tweaks).

@Mark-Simulacrum
Copy link
Member

More concretely, it feels like this PR combines together many refactors in one commit, and that makes it hard for me to understand the intent behind each and evaluate it. (Or figure out when things are intended to depend on each other or be related).

@ssomers
Copy link
Contributor Author

ssomers commented Dec 12, 2020

I can split off some more items from this one and present #79521 separately from any of this PR. But there are (minor) conflicts between them, so I'll just start on #79521 alone.

@ssomers ssomers marked this pull request as draft December 12, 2020 20:10
@ssomers
Copy link
Contributor Author

ssomers commented Dec 13, 2020

Apart from the really small stuff, I see 4 changes that could be here (each repeated for the key, val and edge arrays):

  1. Stop pretending callers of key_area could share references. Which implies all the "area" methods return exclusive access.
  2. Stop implicitly injecting the node's current length in key_area_slice because that introduces a non-obvious order dependency with statements updating length; instead pass length explicitly. Which leaves only 2 "area" methods, taking either a single index or a range.
  3. Introduce SliceIndex to settle on a single "area" method name.
  4. Introduce slice functions to slightly abstract ptr::copy statements and require a source and destination size, so that we can debug-assert sizes the way -Zmiri-track-raw-pointers does.
  5. Finally, not here but in BTreeMap: respect pointer provenance rules in split_off #79347, convert the code around into_kv_pointers to use that infrastructure.

I think (1) is a worth while clarification on its own, but it seems you're not convinced. #79347 does (2) first, but it seemed sensible to combine with (3) rather than come up with additional methods. It's possible to do (4) first , but it causes long lines without all the other tweaks (i.e., #79521, #80006 and (3)).

@ssomers
Copy link
Contributor Author

ssomers commented Dec 13, 2020

Meanwhile, a variation rebased on #79521 and #80006, that abolishes key_area (and cousins) and replaces calls to it instead.

@ssomers ssomers changed the title BTreeMap: lightly refactor a bunch of methods BTreeMap: clean up access to MaybeUninit arrays Dec 13, 2020
@bors
Copy link
Contributor

bors commented Dec 14, 2020

☔ The latest upstream changes (presumably #80005) made this pull request unmergeable. Please resolve the merge conflicts.

Note that reviewers usually do not review pull requests until merge conflicts are resolved! Once you resolve the conflicts, you should change the labels applied by bors to indicate that your PR is ready for review. Post this as a comment to change the labels:

@rustbot modify labels: +S-waiting-on-review -S-waiting-on-author

@bors
Copy link
Contributor

bors commented Dec 25, 2020

☔ The latest upstream changes (presumably #79347) made this pull request unmergeable. Please resolve the merge conflicts.

Note that reviewers usually do not review pull requests until merge conflicts are resolved! Once you resolve the conflicts, you should change the labels applied by bors to indicate that your PR is ready for review. Post this as a comment to change the labels:

@rustbot modify labels: +S-waiting-on-review -S-waiting-on-author

@ssomers ssomers marked this pull request as ready for review December 25, 2020 08:51
@ssomers
Copy link
Contributor Author

ssomers commented Dec 25, 2020

Focusing on the point discussed here, the rest is for later PRs.

PS Another way to defend my crusade against shared access to MaybeUninit slices: we get away with shared access because MaybeUninit is too stupid to remember whether it contains something or not. When we move over items that we access through key_area to another node, we do mutate the source MaybeUninit containers, we uninitialize them.

@Mark-Simulacrum Mark-Simulacrum added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Dec 26, 2020
@Mark-Simulacrum
Copy link
Member

@bors r+ rollup=never

Ok, this seems fine. I think I am at least somewhat convinced by the ownership argument, but ultimately it doesn't matter too much, and this seems to let us delete some unused APIs which is great.

@bors
Copy link
Contributor

bors commented Dec 26, 2020

📌 Commit 0d2548a has been approved by Mark-Simulacrum

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 26, 2020
@bors
Copy link
Contributor

bors commented Dec 26, 2020

⌛ Testing commit 0d2548a with merge 89524d0...

@bors
Copy link
Contributor

bors commented Dec 26, 2020

☀️ Test successful - checks-actions
Approved by: Mark-Simulacrum
Pushing 89524d0 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Dec 26, 2020
@bors bors merged commit 89524d0 into rust-lang:master Dec 26, 2020
@rustbot rustbot added this to the 1.51.0 milestone Dec 26, 2020
@ssomers ssomers deleted the btree_cleanup_1 branch December 26, 2020 20:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants