-
Notifications
You must be signed in to change notification settings - Fork 1.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
Tidy RangeSet #2113
Tidy RangeSet #2113
Conversation
Codecov Report
@@ Coverage Diff @@
## develop #2113 +/- ##
===========================================
+ Coverage 68.98% 68.98% +<.01%
===========================================
Files 684 683 -1
Lines 50461 50369 -92
===========================================
- Hits 34812 34749 -63
+ Misses 15649 15620 -29
Continue to review full report at Codecov.
|
src/test/basics/RangeSet_test.cpp
Outdated
@@ -26,69 +26,132 @@ namespace ripple { | |||
class RangeSet_test : public beast::unit_test::suite | |||
{ | |||
public: | |||
RangeSet createPredefinedSet () | |||
void | |||
testSetAndHas() |
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 are good tests - the only other thing I'd like to see is setRange
with values that overlap and the front/back/middle of an existing range. If that's already there and I missed it, then 👍
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.
Good suggestion. I will add.
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.
Thanks @mellery451, your suggestion uncovered a bug. I'm actually now more tempted to look at Boost ICL after all to avoid these type of errors when rolling our own.
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
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.
Removed code is code that can't break! 👍
Sorry to do this to you @ximinez and @mellery451, but I decided to switch to boost after that last bug was uncovered. I choose to have |
I don't mind a bit! I'll check it out ASAP. |
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.
Nice abstraction. 👍
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 like it
Squash and passed, thanks! |
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.
A couple of minor nits.
In looking at this, I started wondering if we should rethink this interface. I'll comment for posterity, but no action is needed for these:
First of all, get
Firstand
prevMissingreturn this
absentvalue, and I was thinking maybe
boost::optionalwould be better, but then just looking at the way we use
getFirstand
prevMissing` I'm not sure that's right.
getFirst
is a single-use function that leverages the weird semantics of absent
being larger than any possible value. Instead the caller should check if the range is empty, before calling getFirst
.
prevMissing
again has this weird check for 0
and returns absent
.
src/ripple/basics/impl/RangeSet.cpp
Outdated
if (it.first == it.second) | ||
ret += beast::lexicalCastThrow <std::string> ((it.first)); | ||
if (it.first() == it.last()) | ||
ret += beast::lexicalCastThrow<std::string>((it.first())); |
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.
Should we just use std::to_string
here and do away with this beast::lexicalCastThrow<std::string>
nonsense?
src/ripple/basics/RangeSet.h
Outdated
class RangeSet | ||
{ | ||
public: | ||
static const std::uint32_t absent = static_cast <std::uint32_t> (-1); | ||
static const std::uint32_t absent = static_cast<std::uint32_t>(-1); |
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.
Uh-oh... my spidey sense is tingling! I don't like this. At a minimum, let's make it std::numeric_limits<std::uin32_t>::max
.
src/test/basics/RangeSet_test.cpp
Outdated
for (int i = 1; i <= 10; ++i) | ||
{ | ||
if(!BEAST_EXPECT(r.hasValue(i))) | ||
std::cout << i << "\n"; |
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.
std::cout
in a unit 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.
D'oh. Forgot to tidy that.
src/test/basics/RangeSet_test.cpp
Outdated
|
||
BEAST_EXPECT(set.prevMissing (i) == expectedPrevMissing); | ||
BEAST_EXPECT(set.prevMissing(i) == expectedPrevMissing); |
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.
So, prevMissing
returns a std::uint32_t
(which may be initialized to static_int<std::uint32_t>(-1)
) and expectedPrevMissing
is an int
. This smells.
src/ripple/basics/RangeSet.h
Outdated
|
||
// Add an item to the set | ||
void setValue (std::uint32_t); | ||
void setValue(std::uint32_t); |
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 know you went out of your way to not rename things, but since you're here, I think that some renaming makes sense: I'd suggest that hasValue
should be contains
, setValue
and setRange
should really be add
and clearValue
should be remove
.
@bachase The new Shard code uses The new Map type should be boost serialization access friendly as the new Shard class serializes it. Being a boost type it probably is but you may want to check. It should be |
Thanks for the feedback. I'm all for changing the interface as you suggest @nbougalis and @miguelportilla rather than the incremental changes I proposed. I'll also restore |
Get out your 🍅. @miguelportilla checkout https://github.com/bachase/rippled/commits/bc_shard to see the changes I made in your shard work. |
@bachase I like the simplification of an alias and some free functions. The shard changes look good. Using |
978f6b5
to
4b00186
Compare
Rebased on 0.70.0-b6 and squashed with just the latest approach since the incremental change isn't particularly useful to see. Note that |
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 like the rewrite.
@@ -365,15 +365,16 @@ LedgerMaster::getFullValidatedRange (std::uint32_t& minVal, std::uint32_t& maxVa | |||
if (!maxVal) | |||
return false; | |||
|
|||
boost::optional<std::uint32_t> maybeMin; |
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'm going with the idea that it's not worth changing the interface here to make minVal
an optional
.
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.
If anything, I think changing this to return boost::optional<std::pair<std::uint32_t,std::uint32_t>>
makes better sense.
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. That's a good idea. There's no reason the parameters need to be passed in to start with. Same could be said for getValidatedRange
.
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'm going to punt on that for this PR. I think its worth considering, but better as a refactor/simplification of LedgerMaster
.
} | ||
ScopedLockType sl(mCompleteLock); | ||
if (seq > 0) | ||
mCompleteLedgers.erase(range(0u, seq - 1)); |
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.
Nice simplification. Can mCompleteLock
be changed into a regular mutex
now?
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 think so, but I think the design of LedgerMaster
doesn't enforce it well, so I was wary to change 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.
Maybe out of scope for this change set, considering the extra testing required, but definitely worth taking a close look at.
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.
Nice to see you adopt this change. It greatly simplifies this function and makes it easy to understand what's going on.
@@ -344,14 +344,14 @@ bool | |||
LedgerMaster::haveLedger (std::uint32_t seq) | |||
{ | |||
ScopedLockType sl (mCompleteLock); | |||
return mCompleteLedgers.hasValue (seq); | |||
return boost::icl::contains(mCompleteLedgers, seq); |
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.
Is it worth adding another free function to "hide" the boost::icl
in this one case? Probably not.
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'd rather we don't. Rationale: it's just a function which only hides the type and complicates the codebase for anyone trying to understand. Seeing boost::
is enough for most people to say "Oh, that's Boost.. fine, I won't worry about that" unless they really need to, and in this case, they probably won't since the names are actually good enough.
@@ -344,14 +344,14 @@ bool | |||
LedgerMaster::haveLedger (std::uint32_t seq) | |||
{ | |||
ScopedLockType sl (mCompleteLock); | |||
return mCompleteLedgers.hasValue (seq); | |||
return boost::icl::contains(mCompleteLedgers, seq); |
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'd rather we don't. Rationale: it's just a function which only hides the type and complicates the codebase for anyone trying to understand. Seeing boost::
is enough for most people to say "Oh, that's Boost.. fine, I won't worry about that" unless they really need to, and in this case, they probably won't since the names are actually good enough.
} | ||
ScopedLockType sl(mCompleteLock); | ||
if (seq > 0) | ||
mCompleteLedgers.erase(range(0u, seq - 1)); |
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.
Nice to see you adopt this change. It greatly simplifies this function and makes it easy to understand what's going on.
@@ -365,15 +365,16 @@ LedgerMaster::getFullValidatedRange (std::uint32_t& minVal, std::uint32_t& maxVa | |||
if (!maxVal) | |||
return false; | |||
|
|||
boost::optional<std::uint32_t> maybeMin; |
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.
If anything, I think changing this to return boost::optional<std::pair<std::uint32_t,std::uint32_t>>
makes better sense.
Merged into 0.80.0-b1 |
@wufeipeng fix an issue in #2109 in the unused
getPrev
function ofRangeSet
. This is an alternate fix, which eliminates several unused members ofRangeSet
and increases test coverage of the remaining member functions.