-
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
Simplify NodeHeader by avoiding slices in BTreeMaps with shared roots #67686
Conversation
r? @kennytm (rust_highfive has picked a reviewer for you, use r? to override) |
r? @RalfJung |
The simplification stems from the observation that slices on immutable trees are almost exclusively used to This might cure current & future bugs and enable change because it's easier to understand, and it might cause future bugs and hinders changes because of a somewhat sneaky precondition "shared roots not welcome here" introduced in the (very locally) public function Tests fine on 32-bit & 64-bit Windows, Linux & Miri (with debug assertions). Performance change (without debug assertions :^)
In my experience, this means there is no difference. The optimizer just chooses to focus on some other test cases. One alternative is to take this a step further: don't make slices at all, and don't sneak in a precondition, but require a very visible index argument as implemented in this branch. This also - avoids "leaking" the slice concept outside node.rs (so for instance, storing a key-value pair as a pair would be local to the file). |
Regarding your last comment at #67459 (comment):
I don't follow, didn't you say that |
@@ -508,47 +504,9 @@ impl<'a, K, V, Type> NodeRef<marker::Mut<'a>, K, V, Type> { | |||
|
|||
impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> { | |||
fn into_key_slice(self) -> &'a [K] { |
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.
Maybe add a doc comment saying that it is up to the caller to ensure that this is not the shared root?
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.
For an internal function, isn't the assert obvious enough?
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.
It's still a big file. But I don't feel very strongly about this one.
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.
I would like to see this function made unsafe and a comment on it that it is unsafe to call with a shared root.
Alternatively, I think it is plausible that we can keep it safe and make the assert non-debug (realistically the one constant-comparison seems super unlikely to be the performance problem in real world code), when we're dealing with a BTreeMap that's comparing right and left anyway.
I'm a big fan of this, but I don't know |
Also Cc @Gankra |
This comment has been minimized.
This comment has been minimized.
Oh I see. Is that the |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
cbeacc7
to
de7939b
Compare
Turns out that this comment (on |
de7939b
to
125b4c3
Compare
I moved everything that doesn't directly relate to the |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
125b4c3
to
1184277
Compare
a731b21
to
9e90840
Compare
@@ -508,47 +504,9 @@ impl<'a, K, V, Type> NodeRef<marker::Mut<'a>, K, V, Type> { | |||
|
|||
impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> { | |||
fn into_key_slice(self) -> &'a [K] { |
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.
I would like to see this function made unsafe and a comment on it that it is unsafe to call with a shared root.
Alternatively, I think it is plausible that we can keep it safe and make the assert non-debug (realistically the one constant-comparison seems super unlikely to be the performance problem in real world code), when we're dealing with a BTreeMap that's comparing right and left anyway.
I would like to see the functions that cannot be called on the shared root made unsafe (yes, it seems like that probably means everything ends up being unsafe, but that's fine IMO) -- better than pretending it's safe. Other than that, I believe this PR is ready to land. |
Including functions like |
Ah, I meant specifically the ones we've changed in this PR (into_key_slice was the one specifically that I meant). But yes, the rest can be done in a separate PR. |
I am torn here... I agree in principle they should be unsafe, but some of these function are non-trivial in size, and without rust-lang/rfcs#2585 we'll lose all syntactic indication of which operations in them need extra scrutiny. |
Yeah, I agree it's not quite clear that it'll be a win. I would at least like to see us make sure that the functions are properly annotated with the preconditions that must hold before we do much more refactoring on the APIs, as currently it's sort of "dig into the function and figure it out" each time. |
There's actually not much lost, to my surprise, when I do the same changes in the master preceding this PR (not fully tested yet). It still seems an unfair treatment with regards to |
We would want to apply the same treatment there, too. But it's not immediately clear based on the diff exactly what you mean in terms not losing much -- I would need to dig in further. Overall though I think the most important thing in this case (for private code) is not the unsafe annotation so much as documenting preconditions. |
I meant that most of the functions in node.rs that become unsafe, didn't have any subtle distinction between unsafe blocks and safe parts. That code is mostly in map.rs, and there this change only adds (even) more unsafe blocks. |
Those are there now, both informally (comment line) and very formally (debug_assert). |
@bors r+ I would like to spend some time myself digging into the code to try and ensure we've documented all the preconditions and so forth, but that need not block this PR, which I believe is in a sufficiently good state to merge. Let's move forward. |
📌 Commit 3e947ef has been approved by |
…Simulacrum Simplify NodeHeader by avoiding slices in BTreeMaps with shared roots Simplify a complicated piece of code that creates slices of keys in node leaves.
Rollup of 7 pull requests Successful merges: - #67686 (Simplify NodeHeader by avoiding slices in BTreeMaps with shared roots) - #68140 (Implement `?const` opt-out for trait bounds) - #68313 (Options IP_MULTICAST_TTL and IP_MULTICAST_LOOP are 1 byte on BSD) - #68328 (Actually pass target LLVM args to LLVM) - #68399 (check_match: misc unifications and ICE fixes) - #68415 (tidy: fix most clippy warnings) - #68416 (lowering: cleanup some hofs) Failed merges: r? @ghost
☔ The latest upstream changes (presumably #68423) made this pull request unmergeable. Please resolve the merge conflicts. |
Simplify a complicated piece of code that creates slices of keys in node leaves.