Commit 699de95c authored by Patrick Monette's avatar Patrick Monette Committed by Commit Bot

Add IntrusiveHeap::Modify()

This new member function allows the caller to modify an element in-place
safely. The existing options to do this right now is either use
const_cast<> then call Update() manually (was done by tests), or remove
then reinsert the modified element afterwards. The issue with the later
option is that you can't keep using the same HeapHandle pointer as it
cleared during the removal.

Bug: 971272
Change-Id: I202daa322f1160d601ffffa87ceb6a4dad0e291f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2530370Reviewed-by: default avatarAlbert J. Wong <ajwong@chromium.org>
Reviewed-by: default avatarChris Hamilton <chrisha@chromium.org>
Commit-Queue: Patrick Monette <pmonette@chromium.org>
Cr-Commit-Position: refs/heads/master@{#827928}
parent f155b5f9
...@@ -445,6 +445,16 @@ class IntrusiveHeap { ...@@ -445,6 +445,16 @@ class IntrusiveHeap {
return Update(ToIndex(pos)); return Update(ToIndex(pos));
} }
// Applies a modification function to the object at the given location, then
// repairs the heap. To be used to modify an element in the heap in-place
// while keeping the heap intact.
template <typename P, typename UnaryOperation>
const_iterator Modify(P pos, UnaryOperation unary_op) {
size_type index = ToIndex(pos);
unary_op(impl_.heap_.at(index));
return Update(index);
}
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// Access to helper functors. // Access to helper functors.
......
...@@ -246,9 +246,8 @@ void DoSameSizeOperation(IntrusiveHeap<T>* heap) { ...@@ -246,9 +246,8 @@ void DoSameSizeOperation(IntrusiveHeap<T>* heap) {
} }
case kUpdate: { case kUpdate: {
T* t = const_cast<T*>(&heap->at(index)); it = heap->Modify(
t->set_value(new_value); index, [&new_value](T& element) { element.set_value(new_value); });
it = heap->Update(index);
break; break;
} }
...@@ -413,6 +412,10 @@ void GeneralStressTest() { ...@@ -413,6 +412,10 @@ void GeneralStressTest() {
heap.Update(7u); heap.Update(7u);
ExpectHeap(heap); ExpectHeap(heap);
// Safely modify an element that is already inside the heap.
heap.Modify(7u, [](T& element) { element.set_value(128); });
ExpectHeap(heap);
// Do some more updates that are no-ops, just to explore all the flavours of // Do some more updates that are no-ops, just to explore all the flavours of
// ToIndex. // ToIndex.
handle = heap[5].handle(); handle = heap[5].handle();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment