chore: get rid of sds in SortedMap::AddElem (#4638)

chore: get rid of sds in SortedMap functions

Switch them to string_view interfaces.

Signed-off-by: Roman Gershman <roman@dragonflydb.io>
This commit is contained in:
Roman Gershman 2025-02-21 11:07:53 +02:00 committed by GitHub
parent 8226d555c6
commit 54b864b2c7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 38 additions and 32 deletions

View file

@ -597,13 +597,6 @@ bool RobjWrapper::DefragIfNeeded(float ratio) {
}
int RobjWrapper::ZsetAdd(double score, sds ele, int in_flags, int* out_flags, double* newscore) {
// copied from zsetAdd for listpack only.
/* Turn options into simple to check vars. */
bool incr = (in_flags & ZADD_IN_INCR) != 0;
bool nx = (in_flags & ZADD_IN_NX) != 0;
bool xx = (in_flags & ZADD_IN_XX) != 0;
bool gt = (in_flags & ZADD_IN_GT) != 0;
bool lt = (in_flags & ZADD_IN_LT) != 0;
*out_flags = 0; /* We'll return our response flags. */
double curscore;
@ -615,6 +608,13 @@ int RobjWrapper::ZsetAdd(double score, sds ele, int in_flags, int* out_flags, do
/* Update the sorted set according to its encoding. */
if (encoding_ == OBJ_ENCODING_LISTPACK) {
/* Turn options into simple to check vars. */
bool incr = (in_flags & ZADD_IN_INCR) != 0;
bool nx = (in_flags & ZADD_IN_NX) != 0;
bool xx = (in_flags & ZADD_IN_XX) != 0;
bool gt = (in_flags & ZADD_IN_GT) != 0;
bool lt = (in_flags & ZADD_IN_LT) != 0;
unsigned char* eptr;
uint8_t* lp = (uint8_t*)inner_obj_;
@ -678,7 +678,8 @@ int RobjWrapper::ZsetAdd(double score, sds ele, int in_flags, int* out_flags, do
CHECK_EQ(encoding_, OBJ_ENCODING_SKIPLIST);
SortedMap* ss = (SortedMap*)inner_obj_;
return ss->Add(score, ele, in_flags, out_flags, newscore);
string_view elem(ele, sdslen(ele));
return ss->AddElem(score, elem, in_flags, out_flags, newscore);
}
void RobjWrapper::ReallocateString(MemoryResource* mr) {

View file

@ -108,9 +108,8 @@ class ScoreMap : public DenseSet {
/// @return sds
std::optional<double> Find(std::string_view key);
// returns the internal object if found, otherwise nullptr.
void* FindObj(sds ele) {
return FindInternal(ele, Hash(ele, 0), 0);
void* FindObj(std::string_view sv) {
return FindInternal(&sv, Hash(&sv, 1), 1);
}
iterator begin() {

View file

@ -233,21 +233,27 @@ int SortedMap::ScoreSdsPolicy::KeyCompareTo::operator()(ScoreSds a, ScoreSds b)
return sdscmp(sdsa, sdsb);
}
int SortedMap::Add(double score, sds ele, int in_flags, int* out_flags, double* newscore) {
int SortedMap::AddElem(double score, std::string_view ele, int in_flags, int* out_flags,
double* newscore) {
// does not take ownership over ele.
DCHECK(!isnan(score));
// TODO: to introduce AddOrFind in score_map.
ScoreSds obj = score_map->FindObj(ele);
ScoreSds obj = nullptr;
bool added = false;
if (obj == nullptr) {
// Adding a new element.
if (in_flags & ZADD_IN_XX) {
if (in_flags & ZADD_IN_XX) {
obj = score_map->FindObj(ele);
if (obj == nullptr) {
*out_flags = ZADD_OUT_NOP;
return 1;
}
} else {
tie(obj, added) = score_map->AddOrSkip(ele, score);
}
obj = score_map->AddUnique(string_view{ele, sdslen(ele)}, score);
if (added) {
// Adding a new element.
DCHECK_EQ(in_flags & ZADD_IN_XX, 0);
*out_flags = ZADD_OUT_ADDED;
*newscore = score;
@ -302,7 +308,7 @@ bool SortedMap::InsertNew(double score, std::string_view member) {
return true;
}
optional<unsigned> SortedMap::GetRank(sds ele, bool reverse) const {
optional<unsigned> SortedMap::GetRank(std::string_view ele, bool reverse) const {
ScoreSds obj = score_map->FindObj(ele);
if (obj == nullptr)
return std::nullopt;
@ -777,7 +783,8 @@ bool SortedMap::DefragIfNeeded(float ratio) {
return reallocated;
}
std::optional<SortedMap::RankAndScore> SortedMap::GetRankAndScore(sds ele, bool reverse) const {
std::optional<SortedMap::RankAndScore> SortedMap::GetRankAndScore(std::string_view ele,
bool reverse) const {
ScoreSds obj = score_map->FindObj(ele);
if (obj == nullptr)
return std::nullopt;

View file

@ -52,7 +52,7 @@ class SortedMap {
};
bool Reserve(size_t sz);
int Add(double score, sds ele, int in_flags, int* out_flags, double* newscore);
int AddElem(double score, std::string_view ele, int in_flags, int* out_flags, double* newscore);
// Inserts a new element. Returns false if the element already exists.
// No score update is performed in this case.
@ -76,8 +76,8 @@ class SortedMap {
ScoredArray PopTopScores(unsigned count, bool reverse);
std::optional<double> GetScore(sds ele) const;
std::optional<unsigned> GetRank(sds ele, bool reverse) const;
std::optional<RankAndScore> GetRankAndScore(sds ele, bool reverse) const;
std::optional<unsigned> GetRank(std::string_view ele, bool reverse) const;
std::optional<RankAndScore> GetRankAndScore(std::string_view ele, bool reverse) const;
ScoredArray GetRange(const zrangespec& r, unsigned offs, unsigned len, bool rev) const;
ScoredArray GetLexRange(const zlexrangespec& r, unsigned o, unsigned l, bool rev) const;

View file

@ -48,21 +48,22 @@ TEST_F(SortedMapTest, Add) {
int out_flags;
double new_score;
sds ele = sdsnew("a");
int res = sm_.Add(1.0, ele, 0, &out_flags, &new_score);
int res = sm_.AddElem(1.0, "a", 0, &out_flags, &new_score);
EXPECT_EQ(1, res);
EXPECT_EQ(ZADD_OUT_ADDED, out_flags);
EXPECT_EQ(1, new_score);
res = sm_.Add(2.0, ele, ZADD_IN_NX, &out_flags, &new_score);
res = sm_.AddElem(2.0, "a", ZADD_IN_NX, &out_flags, &new_score);
EXPECT_EQ(1, res);
EXPECT_EQ(ZADD_OUT_NOP, out_flags);
res = sm_.Add(2.0, ele, ZADD_IN_INCR, &out_flags, &new_score);
res = sm_.AddElem(2.0, "a", ZADD_IN_INCR, &out_flags, &new_score);
EXPECT_EQ(1, res);
EXPECT_EQ(ZADD_OUT_UPDATED, out_flags);
EXPECT_EQ(3, new_score);
sds ele = sdsnew("a");
EXPECT_EQ(3, sm_.GetScore(ele));
sdsfree(ele);
}
TEST_F(SortedMapTest, Scan) {
@ -285,9 +286,7 @@ TEST_F(SortedMapTest, ReallocIfNeeded) {
int out_flags;
double new_val;
auto str = build_str(i);
sds ele = sdsnew(str.c_str());
sm_.Add(i, ele, 0, &out_flags, &new_val);
sdsfree(ele);
sm_.AddElem(i, str, 0, &out_flags, &new_val);
}
for (size_t i = 0; i < 10'000; i++) {

View file

@ -1227,14 +1227,14 @@ OpResult<RankResult> OpRank(const OpArgs& op_args, string_view key, string_view
RankResult res{};
if (with_score) {
auto rankAndScore = ss->GetRankAndScore(WrapSds(member), reverse);
auto rankAndScore = ss->GetRankAndScore(member, reverse);
if (!rankAndScore) {
return OpStatus::KEY_NOTFOUND;
}
res.rank = rankAndScore->first;
res.score = rankAndScore->second;
} else {
std::optional<unsigned> rank = ss->GetRank(WrapSds(member), reverse);
std::optional<unsigned> rank = ss->GetRank(member, reverse);
if (!rank) {
return OpStatus::KEY_NOTFOUND;
}