-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
Refactor: Replace parts of boost::optional with std::optional (#6551,… #6593
Conversation
Tests fail with segfault. |
Had something to do with DecreaseKey in query_heap.hpp. |
328eaaf
to
97d3fcb
Compare
Relevant documentation includes: |
std::remove_if(non_core_edges.begin(), non_core_edges.end(), [&](const auto &edge) { | ||
return is_shared_core[edge.source] && is_shared_core[edge.target]; | ||
}); | ||
auto new_end = std::remove_if(non_core_edges.begin(), |
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.
Hm, do I get it correctly that most of changes in this PR are format changes. Were they pushed by mistake?
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.
Better now ?
1fc8d4c
to
f98d73c
Compare
include/util/query_heap.hpp
Outdated
@@ -289,7 +289,7 @@ class QueryHeap | |||
return inserted_nodes[index].node == node; | |||
} | |||
|
|||
boost::optional<HeapNode &> GetHeapNodeIfWasInserted(const NodeID node) | |||
std::optional<HeapNode> GetHeapNodeIfWasInserted(NodeID node) |
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.e. now on each call we will copy HeapNode, right? How do we know that it won’t impact performance? May be worth refactoring it to HeapNode*
instead(I mean use just pointer instead of optional here)? From some perspective optional<T&> is just overcomplicated way to express simple pointer…
WDYT?
P.S. I didn’t have a time yet to look over the rest of PR, just something important what I noticed…
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.
More than it: here you can see an example when we change contents of node in a heap and that by reference…
toHeapNode->data = {heapNode.node, true}; |
I.e. if we return it not by reference now most likely existing logic is broken.
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 did run my build and it did at least not segfault or got killed by kernel for too much RAM.
To cite from cppreference.com:
"There are no optional references; a program is ill-formed if it instantiates an optional with a reference type."
Search engine would suggest std::reference_wrapper for this task.
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.
At the same time as I can see if we just change it to simple pointer instead of optional(I.e. won’t use neither boost::optional nor std::optional) the rest of code which uses this QueryHeap would “just work” without changes we had to make there…
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.
Regarding the other comment std::optional defines an operator->. However in some cases you probably would need to change a deref etc. I'm just testing solely using pointers for these parts. Does not work out of the box, but the idea should be doable.
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.
boost::optional<T&>
seems to be effectively the same as T*
, isn’t it?
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.
Yes it is. Still forking the main branch I need replace some of the idioms. Do you prefer nullptr or some void coercion ?
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.
What is void coercion? You mean if (ptr == nullptr)
vs if (!ptr)
? Personally I like first option as more explicit, but I don’t think it would be blocker to merge this PR :)
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.
Actually it's dreadfully simple, memory safety should be fine since it tests. I got too fed up with the nullptr version.
I think you need to approve CI again.
54ef1b3
to
fb0400f
Compare
include/util/query_heap.hpp
Outdated
@@ -356,13 +356,13 @@ class QueryHeap | |||
const auto index = node_index.peek_index(node); | |||
auto &reference = inserted_nodes[index]; | |||
reference.weight = weight; | |||
heap.increase(reference.handle, std::make_pair(weight, index)); | |||
heap.decrease(reference.handle, std::make_pair(weight, index)); |
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.
This change is pretty fundamental to how the whole routing algorithm works. Can you explain exactly why this change is being made here?
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.
See my previous link posted above:
https://www.boost.org/doc/libs/1_76_0/doc/html/boost/heap/d_ary_heap.html#id-1_3_18_6_2_1_1_1_22_17-bb
My thoughts behind this are that there is logic in multiple files e.g. include/engine/routing_algorithms/routing_base_mld.hpp that checks for a certain "to_weight" to be smaller than the current "toHeapNode->weight" and then calls DecreaseKey which in turn calls heap.increase with "to_weight".
So the docs say: "The new value is expected to be less than the current one" for decrease not increase.
Also I guess it kinda fixed a segfault for me while testing. (I know for sure it was this one, however might only have emerged with now reverted changes since now not using std::optional instead just pointers)
Am I completely mistaken here ? I still get from A to B though using my setup e.g. with the Germany map.
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.
Can you explain why the change from heap.increase()
to heap.decrease()
? "The old version was wrong because XYZ?" is an acceptable answer, but this is a pretty fundamental change to a core part of the routing algorithm, I think it needs a clear rationale.
@SiarheiFedartsou @danpat |
@mugr1x You didn't address my question about the changes in |
Well I linked the docs two times and explained my reasoning. I opened a separate issue #6603 for this but I would really advise you too look into this anyway soonish. As said I fixed a segfault at some point for me. |
Can we discuss that in separate PR? This change is serious enough to deserve separate PR... Also if you see that it doesn't work in certain cases it is always a good practice to add test for such case to not regress it in the future. |
Yes |
I just noted that PR #6596 was merged, I had the same fix as that in this PR too. So I just resolved this one with master. |
Hi @mugr1x , I took a glance at that error you mentioned and it looks like the file where |
@danpat Are you happy with the current status ? If so can you close the review or similar. |
CI shows exactly the same error about block_counter, which is weird since it is clearly only defined once now, also in diff. |
@mugr1x may I ask you to create one more empty commit to trigger CI again? I suspect it is some bug in GitHub Actions. |
BlockT block; | ||
#ifndef BOOST_ASSERT_IS_VOID | ||
unsigned block_counter = 0; |
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.
These changes were merged to master in another PR #6596 - they should not also be showing up in this PR. I suspect some merges have been incorrectly applied or lost on the branch. This is probably also why CI is failing. I suspect if you tidy this up, CI should pass.
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.
The source code on master branch has block_counter = 0
on line 85, meanwhile in this commit it is placed on line 84. Could that be what's causing CI to fail?
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.
@mugr1x may be try to squash all your commits into single one? Or open another PR? Tbh for me it is not clear why it is happening - looks more like some GH bug.
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.
@AlTimofeyev Well yes. Idk that much about CI.
@SiarheiFedartsou I did so #6611. Should I close this one ?
I also tried to rewrite some parsers. Point here is that the ones that are easy to rewrite work fine with switching to std::optional but the /server core API (and /engine because it there are crosslinks) don't.
I think this would be considered a too breaking change (at least ~1k lines of code) of new parser-related code.
Do you think there is value in #6592 or should I close this too ?
Also off-topic, but did you receive my email regarding GSoC. I was asking for what you mentors would expect. (I submitted my second version a bit late, though in time. Hope that is not a problem.)
I just realized I had a lot of comments show as 'Pending', which means appearantly noone but me could seee those. |
Issue
Since C++17 added support for 'containers', #6551 targets at replacing current code that uses boost::optional to use std::optional. This PR replaces some parts of the codebase with std::optional, indeed the ones I could convert without having to rewrite some parsers, see #6592 . I try complete these parser, but without that any further migrations to std::optional cause only myriads of compiler errors.
Please read our documentation on release and version management.
If your PR is still work in progress please attach the relevant label.
Tasklist
Requirements / Relations
#6551
#6592