-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Rewrite BTreeMap to use parent pointers. #30426
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @alexcrichton (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
🙀 🎆 🎊 |
wtf github is censoring the two most important files because this PR is too epic. |
Note to self: make sure that we don't actually guarantee the no-allocation property. |
🎉 🎉 🎉 |
☔ The latest upstream changes (presumably #30325) made this pull request unmergeable. Please resolve the merge conflicts. |
Make tidy fixed, but it is really ugly. There is no pretty way to format a very long function signature under 100 characters. |
39b47d2
to
0027ccb
Compare
Rebased. |
0027ccb
to
030820a
Compare
I'm a little concerned about allocating on creation, is there any way around it? Edit: I believe using an Option on the root is a small price to pay for allocation free creation. |
Note that the PR description is incorrect in describing this as a regression; this has always been the case. |
I see but the reasoning is the same. Adding an option around the root node adds a single highly predictable branch, it shouldn't add more than a nanosecond or two to the timings. |
☔ The latest upstream changes (presumably #29973) made this pull request unmergeable. Please resolve the merge conflicts. |
The old BTreeMap code seemed to allocate in |
Oh, whoops - I misremembered the BTreeMap behavior. There is no allocation on empty change. |
@arthurprs your issue is orthogonal to this PR. Changing the map to use Option (or whatevs) can be done at a later date if desirable. |
@gankro fair enough |
@gereeter needs rebase :( Will start review once rebase is done (sorry I've been cleaning up some loose ends at home). |
030820a
to
75a2131
Compare
Rebased. I'm still working on figuring out the segfault, which is especially annoying because it isn't triggering in my simplified tests and isn't hitting any debug assertions. |
Argh, Github is actually making it impossible to comment on the code! |
I'm reviewing this on Reviewable. Comments from the review on Reviewable.io |
Review status: 0 of 5 files reviewed at latest revision, 69 unresolved discussions, some commit checks failed. src/libcollections/btree/map.rs, line 69 [r2] (raw file): Note to self: src/libcollections/btree/node.rs, line 32 [r2] (raw file): src/libcollections/btree/node.rs, line 43 [r2] (raw file): src/libcollections/btree/node.rs, line 48 [r2] (raw file): src/libcollections/btree/node.rs, line 53 [r2] (raw file): src/libcollections/btree/node.rs, line 60 [r2] (raw file): src/libcollections/btree/node.rs, line 83 [r2] (raw file): src/libcollections/btree/node.rs, line 108 [r2] (raw file): src/libcollections/btree/node.rs, line 114 [r2] (raw file): src/libcollections/btree/node.rs, line 118 [r2] (raw file): src/libcollections/btree/node.rs, line 129 [r2] (raw file): src/libcollections/btree/node.rs, line 153 [r2] (raw file): src/libcollections/btree/node.rs, line 160 [r2] (raw file): Also: opposite of shrink is grow? Bikeshed: push_level, pop_level src/libcollections/btree/node.rs, line 174 [r2] (raw file): src/libcollections/btree/node.rs, line 184 [r2] (raw file): Also: this assumes this node stores no keys/vals. src/libcollections/btree/node.rs, line 208 [r2] (raw file): Note to self: verify that this is done at usage sites! src/libcollections/btree/node.rs, line 224 [r2] (raw file): src/libcollections/btree/node.rs, line 225 [r2] (raw file): src/libcollections/btree/node.rs, line 228 [r2] (raw file): src/libcollections/btree/node.rs, line 229 [r2] (raw file):
Decoupling Lifetime and Mutability over
has two benefits:
Otherwise, the two applicable impls would need to be selected manually and duplicated. However this makes everything just a bit more complicated. Alternatively, one could take the Ownership route and select subsets with trait dispatch (Ownership: Mutable; Ownership: Lifetime<'a>). src/libcollections/btree/node.rs, line 232 [r2] (raw file): src/libcollections/btree/node.rs, line 240 [r2] (raw file): Can't pull an &mut T out and boot-strap a Send of T. src/libcollections/btree/node.rs, line 247 [r2] (raw file): Interestingly, I think you could use src/libcollections/btree/node.rs, line 281 [r2] (raw file): src/libcollections/btree/node.rs, line 290 [r2] (raw file): src/libcollections/btree/node.rs, line 293 [r2] (raw file): Not making full aggressive use of elision?! (this is reasonable) Would be interested in a comment explaining wtf this is useful for (guessing Owned -> Borrowed, but is Note to self: 'old: 'a is implied by the existence (WF'ness) of src/libcollections/btree/node.rs, line 316 [r2] (raw file): (also doc plz) src/libcollections/btree/node.rs, line 324 [r2] (raw file): src/libcollections/btree/node.rs, line 326 [r2] (raw file): src/libcollections/btree/node.rs, line 335 [r2] (raw file): src/libcollections/btree/node.rs, line 348 [r2] (raw file): src/libcollections/btree/node.rs, line 399 [r2] (raw file): src/libcollections/btree/node.rs, line 410 [r2] (raw file): src/libcollections/btree/node.rs, line 449 [r2] (raw file): Look I'm not even reading these anymore. If the type system isn't catching all possible errors, I don't even know what to believe in (actually this is all hilariously brittle to incorrect type bounds and global assumptions about state). src/libcollections/btree/node.rs, line 477 [r2] (raw file): src/libcollections/btree/node.rs, line 503 [r2] (raw file): src/libcollections/btree/node.rs, line 513 [r2] (raw file): src/libcollections/btree/node.rs, line 518 [r2] (raw file): src/libcollections/btree/node.rs, line 531 [r2] (raw file): src/libcollections/btree/node.rs, line 532 [r2] (raw file): src/libcollections/btree/node.rs, line 551 [r2] (raw file): src/libcollections/btree/node.rs, line 556 [r2] (raw file): Let's Just Be C? src/libcollections/btree/node.rs, line 561 [r2] (raw file): src/libcollections/btree/node.rs, line 615 [r2] (raw file): src/libcollections/btree/node.rs, line 637 [r2] (raw file): src/libcollections/btree/node.rs, line 640 [r2] (raw file): src/libcollections/btree/node.rs, line 648 [r2] (raw file): src/libcollections/btree/node.rs, line 697 [r2] (raw file): src/libcollections/btree/node.rs, line 728 [r2] (raw file): No wait, wtf is an edge from a leaf?! (I guess this is the generic term for "between keys") src/libcollections/btree/node.rs, line 746 [r2] (raw file): It just occured to me that there's no logic docs in this file... lost in the rewrite, or did we really never have any? (or is it all hoisted up into high-level BTree stuff?) Also: spooky inference of the handle type, interesting! src/libcollections/btree/node.rs, line 750 [r2] (raw file): src/libcollections/btree/node.rs, line 755 [r2] (raw file): src/libcollections/btree/node.rs, line 756 [r2] (raw file): src/libcollections/btree/node.rs, line 769 [r2] (raw file): src/libcollections/btree/node.rs, line 793 [r2] (raw file): src/libcollections/btree/node.rs, line 826 [r2] (raw file): src/libcollections/btree/node.rs, line 844 [r2] (raw file): src/libcollections/btree/node.rs, line 929 [r2] (raw file): src/libcollections/btree/node.rs, line 945 [r2] (raw file): src/libcollections/btree/node.rs, line 967 [r2] (raw file): src/libcollections/btree/node.rs, line 978 [r2] (raw file): src/libcollections/btree/node.rs, line 984 [r2] (raw file): src/libcollections/btree/node.rs, line 992 [r2] (raw file): src/libcollections/btree/node.rs, line 1001 [r2] (raw file): I think these are both supposed to be (this might be your segfault!) src/libcollections/btree/node.rs, line 1009 [r2] (raw file): src/libcollections/btree/node.rs, line 1015 [r2] (raw file): src/libcollections/btree/node.rs, line 1026 [r2] (raw file): src/libcollections/btree/node.rs, line 1096 [r2] (raw file): src/libcollections/btree/node.rs, line 1116 [r2] (raw file): 🎊 Comments from the review on Reviewable.io |
OK. I have done a first pass of node.rs. Sorry this took so long. I like to be reasonably thorough for this kind of stuff, and the holidays slammed me. Thankfully, Reviewable allowed me to save my comments up over the past few weeks! Note that I reviewed just the r2 file, and not the diff (because the diff is pointless). I believe I found what could be your segfault in the impl of Comments from the review on Reviewable.io |
Oh - I think they are just unused, while the previous BTree implementation used them. |
Hmm, I can't tell what's causing Travis to fail now. |
Ah:
|
Yup - I'm not sure why I assumed that |
It passed! |
Niiice. Are there anymore docs you want to write for this, or are we good to go? |
There are more extensive docs that I would like to write eventually, but those will take a while and can always go in a separate PR. |
Ok then, r=me with squash |
56e6554
to
7f07ab8
Compare
7f07ab8
to
cd639d8
Compare
Squashed. |
Oh, should this be marked [breaking-change] since I deleted at least one deprecated function? |
I don't think so, but I'll double check (I'm awful at this sort of thing). |
@huonw says we "might as well" just to be maximally helpful. I don't reckon anyone ever used |
Oh: is |
I added a test for |
@bors r+ 🎊 WE DID IT 🎊 |
📌 Commit be4128d has been approved by |
@brson nominating for relnotes because this is a huge improvement. |
Despite being over 700 lines shorter, this implementation should use less memory than the previous one and is faster on at least insertions and iteration, the latter improving approximately 5x. Technically a [breaking-change] due to removal of deprecated functions. cc @apasel422 @gankro @goyox86 Fixes #27865. <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/rust-lang/rust/30426) <!-- Reviewable:end -->
Despite being over 700 lines shorter, this implementation should use less memory than the previous one and is faster on at least insertions and iteration, the latter improving approximately 5x.
Technically a [breaking-change] due to removal of deprecated functions.
cc @apasel422 @gankro @goyox86
Fixes #27865.