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
fix(set): fix random in SRANDMEMBER and SPOP commands #3022
fix(set): fix random in SRANDMEMBER and SPOP commands #3022
Conversation
|
||
class NonUniquePicksGenerator : public PicksGenerator { | ||
public: | ||
NonUniquePicksGenerator(RandomPick max_range); |
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.
We can add a comment for max_range is open or closed
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.
Fixed
src/server/set_family.cc
Outdated
@@ -284,19 +284,32 @@ void InterStrSet(const DbContext& db_context, const vector<SetType>& vec, String | |||
} | |||
} | |||
|
|||
StringVec PopStrSet(const DbContext& db_context, unsigned count, const SetType& st) { | |||
StringVec RandMemberStrSet(const DbContext& db_context, const SetType& st, | |||
const std::unique_ptr<PicksGenerator>& generator, |
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.
Would a virtual function making it even slower?
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.
- You can pass just const PicksGenerator&
- I don't think the virtual function call adds any mesurable latency 🙂
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 agree with @dranikpg, keep the virtual function call as it was
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.
Sorry if this was not ready for review, just strolling by 👣
src/server/set_family.cc
Outdated
std::copy(result.begin(), result.end(), mapped.begin() + 1); | ||
RecordJournal(op_args, "SREM"sv, mapped); | ||
} | ||
StringVec rand_members = rand_members_result.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.
that's a copy 👮🏻
src/server/set_family.cc
Outdated
ArgSlice span{members_to_remove.data(), members_to_remove.size()}; | ||
|
||
auto rem_members_result = OpRem(op_args, key, span, false); | ||
if (!rem_members_result) { | ||
return rem_members_result.status(); | ||
} |
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.
RETURN_ON_BAD_STATUS(op_args, key, absl::MakeSpan(members), false)
😅
src/server/set_family.cc
Outdated
int count = 1; | ||
if (args.size() > 1) { | ||
string_view arg = ArgS(args, 1); | ||
if (!absl::SimpleAtoi(arg, &count)) { |
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 changes what overload of SimpleAtoi is selected
auto ConsistsOf(std::initializer_list<std::string> elements) { | ||
return ConsistsOfMatcher(std::unordered_set<std::string>{elements}); | ||
} |
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.
Please explain what this means 😀
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.
хороший кот
src/server/set_family.cc
Outdated
std::unique_ptr<PicksGenerator> generator = | ||
picks_are_unique ? static_cast<std::unique_ptr<PicksGenerator>>( | ||
std::make_unique<UniquePicksGenerator>(picks_count, size)) | ||
: std::make_unique<NonUniquePicksGenerator>(size); |
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.
ok mabye the function thing was more readable 😆 You can always also just use a declaration and an if after
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.
Ok, I'll fix it in zset_family.cc
too
src/server/set_family.cc
Outdated
@@ -284,19 +284,32 @@ void InterStrSet(const DbContext& db_context, const vector<SetType>& vec, String | |||
} | |||
} | |||
|
|||
StringVec PopStrSet(const DbContext& db_context, unsigned count, const SetType& st) { | |||
StringVec RandMemberStrSet(const DbContext& db_context, const SetType& st, | |||
const std::unique_ptr<PicksGenerator>& generator, |
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.
- You can pass just const PicksGenerator&
- I don't think the virtual function call adds any mesurable latency 🙂
src/server/set_family.cc
Outdated
std::uint32_t ss_entry_index = 0; | ||
for (const sds ptr : *ss) { | ||
std::uint32_t t = times_index_is_picked[ss_entry_index++]; | ||
while (t--) { | ||
result.emplace_back(ptr, sdslen(ptr)); | ||
} |
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.
you use an unordered_map, but during iteration you'll end up creating every cell up to N because of [ss_entry_index]
, so better use find()
src/server/set_family.cc
Outdated
} | ||
} | ||
|
||
/* Members in result are sorted by scores. So, it is necessary to shuffle them*/ |
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.
Scores? I think you just mean that equal elements are always succesive and we're limited by the string-set order
src/server/set_family.cc
Outdated
int64_t value; | ||
DCHECK_GT(intsetGet(is, picked_index, &value), std::uint8_t(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.
DCHECK it's not called in release builds 🙂
0f19aa7
to
74b498d
Compare
74b498d
to
a1162b7
Compare
fixes dragonflydb#3018 Signed-off-by: Stepan Bagritsevich <sbagritsevich@quantumbrains.com>
a1162b7
to
1111eb5
Compare
Fix a bug where replicas remove other elements during |
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.
👍🏻 (Please push separate commits in the future so it's easier to see changes)
fixes #3018
IntSet
, the time complexity isO(n)
(n
- number of elements to return/remove). The space complexity is alsoO(n)
StrSet
, the time complexity isO(m)
(m
- number of elements in set). The space complexity isO(n)