-
Notifications
You must be signed in to change notification settings - Fork 6.4k
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
BaseDeltaIterator: always check valid() before accessing key() #4702
Conversation
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.
@miasantreble has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.
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.
lgtm
@@ -262,6 +260,7 @@ class BaseDeltaIterator : public Iterator { | |||
} | |||
bool BaseValid() const { return base_iterator_->Valid(); } | |||
bool DeltaValid() const { return delta_iterator_->Valid(); } | |||
bool valid() const { return (current_at_base_ ? BaseValid() : DeltaValid()); } |
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.
how about a name that differs other than capitalization, like BaseDeltaValid
?
As discussed offline, I suggest we revert the original change for now. We only check in the fix if we add the coverage of upper bound in WriteBatchWithIndexTest.TestRandomIteraratorWithBase |
accidentally hit land to master button but looks like land failed due to the network sev. Closing for now, will reopen once test coverage has been added |
@miasantreble has updated the pull request. Re-import the pull request |
Added unit test for iterate_upper_bound in NewIteratorWithBase. Specifically for the case that crashed mysql test: seek to a key outside of upper bound. |
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.
@miasantreble has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.
7c9d5ff
to
e816822
Compare
@miasantreble has updated the pull request. Re-import the pull request |
@siying randomized test added, also fixed a bug uncovered by randomized test. |
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.
@miasantreble has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.
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.
SeekForPrev() using a key not smaller than upper bound is undefined behavior. I think we don't have to complicate the code to handle this case. Rather, we can avoid this in randomize test.
@@ -506,7 +507,17 @@ typedef std::map<std::string, std::string> KVMap; | |||
class KVIter : public Iterator { | |||
public: | |||
explicit KVIter(const KVMap* map) : map_(map), iter_(map_->end()) {} | |||
virtual bool Valid() const { return iter_ != map_->end(); } | |||
explicit KVIter(const KVMap* map, const Slice* iterate_upper_bound) : map_(map), iter_(map_->end()), iterate_upper_bound_(iterate_upper_bound) {} |
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.
80-char
if (iterate_upper_bound_ == nullptr) { | ||
return iter_ != map_->end(); | ||
} | ||
else { |
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.
Formatting
@miasantreble has updated the pull request. Re-import the pull request |
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.
@miasantreble has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.
@miasantreble has updated the pull request. Re-import the pull request |
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.
@miasantreble has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.
@@ -293,6 +293,10 @@ class BaseDeltaIterator : public Iterator { | |||
if (delta_entry.type == kDeleteRecord || | |||
delta_entry.type == kSingleDeleteRecord) { | |||
AdvanceDelta(); | |||
current_over_upper_bound_ = BaseDeltaValid() && IsOverUpperBound(); | |||
if (current_over_upper_bound_) { | |||
break; |
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.
Why not just return from the function here?
@@ -293,6 +293,10 @@ class BaseDeltaIterator : public Iterator { | |||
if (delta_entry.type == kDeleteRecord || | |||
delta_entry.type == kSingleDeleteRecord) { | |||
AdvanceDelta(); | |||
current_over_upper_bound_ = BaseDeltaValid() && IsOverUpperBound(); |
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 use of BaseDeltaValid()
here is somehow confusing. We are advancing delta only in the line above, without updating current_at_base_, we use BaseDeltaValid(). We know it has under if (!BaseValid())
, current_at_base_
won't change, but still, someone trying to understand the code needs to make efforts to understand what's going on here.
It will be slightly better to assert(!current_at_base_)
above this line, and add a comment to explain why.
@miasantreble has updated the pull request. Re-import the pull request |
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.
@miasantreble has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.
…iterator… (facebook#4705)" This reverts commit a21cb22. Recommit a21cb22 as a fix is now available
868bbb2
to
b257d8f
Compare
@miasantreble has updated the pull request. Re-import the pull request |
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.
@miasantreble is landing this pull request. If you are a Facebook employee, you can view this diff on Phabricator.
facebook#4702)" This reverts commit 3a18bb3.
Current implementation of
current_over_upper_bound_
fails to take into consideration that keys might be invalid in either base iterator or delta iterator. Calling key() in such scenario will lead to assertion failure and runtime errors.This PR addresses the bug by adding check for valid keys before calling
IsOverUpperBound()
, also added test coverage for iterate_upper_bound usage in BaseDeltaIteratorAlso recommit #4656 (It was reverted earlier due to bugs)