-
Notifications
You must be signed in to change notification settings - Fork 116
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
Bug Fix for #418 - Graph<T>::removeNode has potential to throw due to optional being accessed early #430
Conversation
auto isolatedNodeIt = isolatedNodesSet.find(nodeOpt.value()); | ||
|
||
auto isolatedNodeIt = isolatedNodesSet.end(); | ||
if (nodeOpt) { | ||
isolatedNodeIt = isolatedNodesSet.find(nodeOpt.value()); | ||
} | ||
|
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 seems ok, but it would be more concise if the entire downstream logic were gated by nodeOpt
, i.e.:
auto nodeOpt = getNode(nodeUserId);
if (nodeOpt)
{
auto isolatedNodeIt = isolatedNodesSet.find(nodeOpt.value());
if (isolatedNodeIt != isolatedNodesSet.end()) {
// Remove the isolated node
...
} else {
// Remove the node and connected edges
...
}
}
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.
Thank you for your feedback, I made a commit with the suggested edits - let me know if it looks okay.
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.
Looks good. Approved
@@ -1340,6 +1340,45 @@ TEST(TestRemoveNode, Test_connectedNode) { | |||
ASSERT_EQ(graph.getEdgeSet().size(), 1); | |||
} | |||
|
|||
TEST(TestRemoveNode, Test_removeInvalidNode) { |
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.
👍
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #430 +/- ##
==========================================
+ Coverage 97.58% 97.87% +0.29%
==========================================
Files 87 87
Lines 9492 10083 +591
Branches 0 666 +666
==========================================
+ Hits 9263 9869 +606
+ Misses 229 214 -15
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
// The node is not isolated | ||
// Remove the edges containing the node | ||
auto edgeset = edgeSet; | ||
for (auto edgeIt : edgeset) { |
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.
Here I would use const auto &
instead of auto
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.
Hi, thank you for your reply. Yes makes sense to use const auto & - no need to make a copy of the edge set, accidentally missed it. When I make that change and use const auto & edgeset = edgeSet, I run into a segmentation fault on the Test_connectedNode test. Not sure how to deal with it. Trying to look through the code to see what the problem could be
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 is likely due to the iterator being invalidated after a successful removal (https://stackoverflow.com/a/16904496/1078527).
The solution is to increment the iterator before removing the element.
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.
Note, that you'll likely need to use the explicit for
loop, instead of iterator-enhanced:
for (auto edgeIt = edgeSet.begin(); edgeIt != edgeSet.end(); ++edgeIt) { ...
This is necessary because std::unordered_set
automatically dereferences iterators in iterator-enhanced for loops (which is why it's crashing).
This also means you'll need a dereference on every iterator access, i.e. (*edgeIt)->
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.
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.
Ah! That's awesome, I hadn't seen that! Thank you!
It's ok, we can wait to merge this due to the license change? |
Pull Request for Bug #418.