Implement extract_if for BinaryHeap#154317
Conversation
|
rustbot has assigned @Mark-Simulacrum. Use Why was this reviewer chosen?The reviewer was selected based on:
|
This comment has been minimized.
This comment has been minimized.
f1ca823 to
7fcbbfb
Compare
This comment has been minimized.
This comment has been minimized.
7fcbbfb to
96ab588
Compare
This comment has been minimized.
This comment has been minimized.
96ab588 to
e2c7e95
Compare
This comment has been minimized.
This comment has been minimized.
- Implement using the sort and rebuild on drop method as maintaining the heap invariant during each extraction would cost more on average
e2c7e95 to
69031cf
Compare
There was a problem hiding this comment.
Nominating for libs-api -- I'd recommend you wait until they discuss before continuing with changes. I think the two topics are (a) do we support extract_if over a subset of the elements, and (2) do we want this at all, given that it can be implemented just as efficiently and fairly easily for the general case on stable today?
| unsafe { | ||
| self.heap.data.set_len(self.old_len - self.del); | ||
| } | ||
| self.heap.rebuild(); |
There was a problem hiding this comment.
Looking through this implementation, it seems to me that we end up replicating Vec::extract_if pretty closely. Maybe we can use it directly, possibly refactoring the impl to allow using it on a passed-in &mut Vec<T, A> for each call (essentially separating the state and the Vec being iterated)?
Alternatively, it's possible that the right pattern is to tell users that the right pattern for extract_if is:
let vec = BinaryHeap::into_sorted_vec(mem::take(heap)); // take only needed if you have only &mut.
vec.extract_if(...);
*heap = BinaryHeap::from(vec);AFAICT, that is equally efficient to the implementation here, and we can't do better since we give &mut T access to the elements: we have to assume all elements were changed by the pass over them, so we can't rebuild more efficiently than re-sifting the whole heap. (Even though in the common case removals happened but probably no changes to the elements occurred).
There was a problem hiding this comment.
I had considered trying to directly reuse the Vec::extract_if impl directly, but I was unable to figure out how to allocate an empty Vec<T> in an arbitrary allocator given only a reference to the allocator
There was a problem hiding this comment.
I have found a way to reuse the Vec::extract_if implementation, PTAL
|
Reminder, once the PR becomes ready for a review, use |
|
We talked about this in today's @rust-lang/libs-api meeting.
|
|
@joshtriplett Thanks for the reply! I'll update the implementation to not sort on creation but still to rebuild on drop. What about providing |
|
Providing a |
|
Is this really worth having over just using (At most a |
|
Currently we cannot |
View all comments
resolves #42849
I have seen #104210 and I took away from reading the comments there that this might be accepted if it does the sort-in-place and then rebuild on drop semantics