fix: node invariant at exception#1454
Conversation
|
|
||
| for ( typename elements_type::const_iterator it = elements.begin() ; | ||
| it != elements.end() ; ++it ) | ||
| BOOST_TRY |
There was a problem hiding this comment.
For review, best to ignore white space changes
|
|
||
| BOOST_RETHROW | ||
| } | ||
| BOOST_CATCH_END |
There was a problem hiding this comment.
See also the part below, it is similar (but not identical). It was just missing here.
| // the behavior of the split exception handler. | ||
| result_elements.clear(); | ||
|
|
||
| auto & elems = rtree::elements(n); |
There was a problem hiding this comment.
Is there a reason for redefining this here? It seems to be the same as elements on line 102, https://github.com/barendgehrels/geometry/blob/ad2761fe3582714d9a6efea8189f2ea25125bda3/include/boost/geometry/index/detail/rtree/rstar/insert.hpp#L102 , which is above the scope of the try-catch block.
There was a problem hiding this comment.
good point I will check it
There was a problem hiding this comment.
The n is a non-const reference so that might be why it is repeated here
There was a problem hiding this comment.
elements.clear(); is also used below.
So probably we should indeed omit it - that makes the two blocks more consistent
I'll try tomorrow
| result_elements.clear(); | ||
|
|
||
| auto & elems = rtree::elements(n); | ||
| if (elems.size() > parameters.get_max_elements()) |
There was a problem hiding this comment.
Is this not already implied by the combination of L102, L104, L108? https://github.com/barendgehrels/geometry/blob/ad2761fe3582714d9a6efea8189f2ea25125bda3/include/boost/geometry/index/detail/rtree/rstar/insert.hpp#L102-L108 , i.e. elements is rtree::elements(n), elements_count is max_elements + 1, then we assert elements.size is elements_count which is max_elements+1. Maybe I am missing something here that can change the value of n but it all looks non-modifying.
There was a problem hiding this comment.
This is the essence of the fix - so yes, it is necessary.
The point is that it is only necessary if something was thrown.
And (apparently) I was (already for a year) the only one who got this, in a unit test, always failing for me...
There was a problem hiding this comment.
Sorry, I didn't mean the entire block. I mean maybe remove just the elems.size() > parameters.get_max_elements() check because it is already guaranteed true. For the destroy_element and the pop_back, I understand those are the essence of the fix. I.e. I propose
--- a/include/boost/geometry/index/detail/rtree/rstar/insert.hpp
+++ b/include/boost/geometry/index/detail/rtree/rstar/insert.hpp
@@ -165,12 +165,8 @@ public:
// the behavior of the split exception handler.
result_elements.clear();
- auto & elems = rtree::elements(n);
- if (elems.size() > parameters.get_max_elements())
- {
- destroy_element<MembersHolder>::apply(elems.back(), allocators);
- elems.pop_back();
- }
+ destroy_element<MembersHolder>::apply(elements.back(), allocators);
+ elements.pop_back();As you state in the new comment https://github.com/barendgehrels/geometry/blob/ad2761fe3582714d9a6efea8189f2ea25125bda3/include/boost/geometry/index/detail/rtree/rstar/insert.hpp#L162
// [...] At this point the node
// has not been modified yet and still contains exactly max+1 elements
This was asserted in L108 before the try catch block and nothing that follows is modifying n or elements (the code only takes const iterators).
|
The overall change seems consistent with the other exception handling case to me, so I am in favor. I left two comments on aspect that are unclear to me. Since you are already touching this function, can you make sense of https://github.com/barendgehrels/geometry/blob/ad2761fe3582714d9a6efea8189f2ea25125bda3/include/boost/geometry/index/detail/rtree/rstar/insert.hpp#L109 ? It seems dubious since it checks an unsigned value for positivity and that unsigned value is also purely a function of parameters, seems like it should move to https://github.com/boostorg/geometry/blame/develop/include/boost/geometry/index/parameters.hpp . |
| @@ -125,32 +125,56 @@ class remove_elements_to_reinsert | |||
| // If constructor is used instead of resize() MS implementation leaks here | |||
| sorted_elements.reserve(elements_count); // MAY THROW, STRONG (V, E: alloc, copy) | |||
There was a problem hiding this comment.
Should this line also go inside the TRY CATCH block since it may also throw and would still leave the node in the invalid state? We can also remove the "copy" from the comment, since reserving on an empty vector should never copy anything. This should only throw if the alloc fails.
Fixes: #1399
Description
This fixes the errors in
boost_geometry_index_rtree_exceptions_rstthat I encountered before.Now with help of Claude Code, reporting:
Solution
By Claude Code:
I reviewed it myself and it looks completely right, and it solves the problem.
@awulkiew can you verify this as well?