diff --git a/src/server/list_family_test.cc b/src/server/list_family_test.cc index ba25153..32dad5e 100644 --- a/src/server/list_family_test.cc +++ b/src/server/list_family_test.cc @@ -57,7 +57,6 @@ TEST_F(ListFamilyTest, Expire) { EXPECT_THAT(resp, IntArg(1)); } - TEST_F(ListFamilyTest, BLPopUnblocking) { auto resp = Run({"lpush", kKey1, "1"}); EXPECT_THAT(resp, IntArg(1)); @@ -158,6 +157,20 @@ TEST_F(ListFamilyTest, BLPopTimeout) { ASSERT_FALSE(service_->IsLocked(0, kKey1)); } +TEST_F(ListFamilyTest, BLPopTimeout2) { + Run({"BLPOP", "blist1", "blist2", "0.1"}); + Run({"RPUSH", "blist2", "d"}); + Run({"RPUSH", "blist2", "hello"}); + auto resp = Run({"BLPOP", "blist1", "blist2", "1"}); + ASSERT_THAT(resp, ArrLen(2)); + ASSERT_THAT(resp.GetVec(), ElementsAre("blist2", "d")); + + Run({"RPUSH", "blist1", "a"}); + Run({"DEL", "blist2"}); + Run({"RPUSH", "blist2", "d"}); + // Run({"BLPOP", "blist1", "blist2", "1"}); +} + TEST_F(ListFamilyTest, LRem) { auto resp = Run({"rpush", kKey1, "a", "b", "a", "c"}); ASSERT_THAT(resp, IntArg(4)); @@ -297,9 +310,7 @@ TEST_F(ListFamilyTest, BPopSameKeyTwice) { this_fiber::sleep_for(30us); } while (!IsLocked(0, kKey1)); - pp_->at(1)->Await([&] { - EXPECT_EQ(1, CheckedInt({"lpush", kKey1, "bar"})); - }); + pp_->at(1)->Await([&] { EXPECT_EQ(1, CheckedInt({"lpush", kKey1, "bar"})); }); pop_fb.join(); ASSERT_THAT(blpop_resp, ArrLen(2)); @@ -313,9 +324,7 @@ TEST_F(ListFamilyTest, BPopSameKeyTwice) { this_fiber::sleep_for(30us); } while (!IsLocked(0, kKey1)); - pp_->at(1)->Await([&] { - EXPECT_EQ(1, CheckedInt({"lpush", kKey2, "bar"})); - }); + pp_->at(1)->Await([&] { EXPECT_EQ(1, CheckedInt({"lpush", kKey2, "bar"})); }); pop_fb.join(); ASSERT_THAT(blpop_resp, ArrLen(2)); diff --git a/src/server/zset_family.cc b/src/server/zset_family.cc index 94d1781..dcc3a30 100644 --- a/src/server/zset_family.cc +++ b/src/server/zset_family.cc @@ -37,38 +37,43 @@ static const char kLexRangeErr[] = "min or max not valid string range item"; constexpr unsigned kMaxListPackValue = 64; -inline zrangespec GetZrangeSpec(const ZSetFamily::ScoreInterval& si) { +inline zrangespec GetZrangeSpec(bool reverse, const ZSetFamily::ScoreInterval& si) { + auto interval = si; + if (reverse) + swap(interval.first, interval.second); + zrangespec range; - range.min = si.first.val; - range.max = si.second.val; - range.minex = si.first.is_open; - range.maxex = si.second.is_open; + range.min = interval.first.val; + range.max = interval.second.val; + range.minex = interval.first.is_open; + range.maxex = interval.second.is_open; return range; } -zlexrangespec GetLexRange(const ZSetFamily::LexInterval& li) { +sds GetLexStr(const ZSetFamily::LexBound& bound) { + if (bound.type == ZSetFamily::LexBound::MINUS_INF) + return cminstring; + + if (bound.type == ZSetFamily::LexBound::PLUS_INF) + return cmaxstring; + + return sdsnewlen(bound.val.data(), bound.val.size()); +}; + +zlexrangespec GetLexRange(bool reverse, const ZSetFamily::LexInterval& li) { + auto interval = li; + if (reverse) + swap(interval.first, interval.second); + zlexrangespec range; range.minex = 0; range.maxex = 0; - if (li.first.type == ZSetFamily::LexBound::MINUS_INF) { - range.min = cminstring; - } else if (li.first.type == ZSetFamily::LexBound::PLUS_INF) { - range.min = cmaxstring; - } else { - range.min = sdsnewlen(li.first.val.data(), li.first.val.size()); - range.minex = (li.first.type == ZSetFamily::LexBound::OPEN); - } - - if (li.second.type == ZSetFamily::LexBound::MINUS_INF) { - range.max = cminstring; - } else if (li.second.type == ZSetFamily::LexBound::PLUS_INF) { - range.max = cmaxstring; - } else { - range.max = sdsnewlen(li.second.val.data(), li.second.val.size()); - range.maxex = (li.second.type == ZSetFamily::LexBound::OPEN); - } + range.min = GetLexStr(interval.first); + range.max = GetLexStr(interval.second); + range.minex = (interval.first.type == ZSetFamily::LexBound::OPEN); + range.maxex = (li.second.type == ZSetFamily::LexBound::OPEN); return range; } @@ -195,7 +200,7 @@ void IntervalVisitor::operator()(const ZSetFamily::IndexInterval& ii) { } void IntervalVisitor::operator()(const ZSetFamily::ScoreInterval& si) { - zrangespec range = GetZrangeSpec(si); + zrangespec range = GetZrangeSpec(params_.reverse, si); switch (action_) { case Action::RANGE: @@ -208,7 +213,7 @@ void IntervalVisitor::operator()(const ZSetFamily::ScoreInterval& si) { } void IntervalVisitor::operator()(const ZSetFamily::LexInterval& li) { - zlexrangespec range = GetLexRange(li); + zlexrangespec range = GetLexRange(params_.reverse, li); switch (action_) { case Action::RANGE: @@ -218,6 +223,7 @@ void IntervalVisitor::operator()(const ZSetFamily::LexInterval& li) { ActionRem(range); break; } + zslFreeLexRange(&range); } void IntervalVisitor::ActionRange(unsigned start, unsigned end) { @@ -1136,7 +1142,6 @@ OpResult ZSetFamily::OpScan(const OpArgs& op_args, std::string_view k ScoredArray arr = iv.PopResult(); res.resize(arr.size() * 2); - for (size_t i = 0; i < arr.size(); ++i) { StringBuilder sb(buf, sizeof(buf)); CHECK(DoubleToStringConverter::EcmaScriptConverter().ToShortest(arr[i].second, &sb)); @@ -1330,7 +1335,7 @@ OpResult ZSetFamily::OpCount(const OpArgs& op_args, std::string_view k return res_it.status(); robj* zobj = res_it.value()->second.AsRObj(); - zrangespec range = GetZrangeSpec(interval); + zrangespec range = GetZrangeSpec(false, interval); unsigned count = 0; if (zobj->encoding == OBJ_ENCODING_LISTPACK) { @@ -1401,7 +1406,7 @@ OpResult ZSetFamily::OpLexCount(const OpArgs& op_args, string_view key return res_it.status(); robj* zobj = res_it.value()->second.AsRObj(); - zlexrangespec range = GetLexRange(interval); + zlexrangespec range = GetLexRange(false, interval); unsigned count = 0; if (zobj->encoding == OBJ_ENCODING_LISTPACK) { uint8_t* zl = (uint8_t*)zobj->ptr; diff --git a/src/server/zset_family_test.cc b/src/server/zset_family_test.cc index 70e1a04..5f70d10 100644 --- a/src/server/zset_family_test.cc +++ b/src/server/zset_family_test.cc @@ -70,7 +70,7 @@ TEST_F(ZSetFamilyTest, ZRangeRank) { EXPECT_THAT(Run({"zrangebyscore", "x", "0", "(1.1"}), ArrLen(0)); EXPECT_THAT(Run({"zrangebyscore", "x", "-inf", "1.1"}), "a"); - auto resp = Run({"zrevrangebyscore", "x", "-inf", "+inf"}); + auto resp = Run({"zrevrangebyscore", "x", "+inf", "-inf"}); ASSERT_THAT(resp, ArgType(RespExpr::ARRAY)); ASSERT_THAT(resp.GetVec(), ElementsAre("b", "a")); @@ -134,8 +134,14 @@ TEST_F(ZSetFamilyTest, ByLex) { ASSERT_THAT(resp.GetVec(), ElementsAre("alpha", "bar", "cool", "down", "elephant", "foo")); } +TEST_F(ZSetFamilyTest, ZRevRange) { + Run({"zadd", "key", "-inf", "a", "1", "b", "2", "c"}); + auto resp = Run({"zrevrangebyscore", "key", "2", "-inf"}); + EXPECT_THAT(resp, ArrLen(3)); +} + TEST_F(ZSetFamilyTest, ZScan) { - string prefix(128,'a'); + string prefix(128, 'a'); for (unsigned i = 0; i < 100; ++i) { Run({"zadd", "key", "1", absl::StrCat(prefix, i)}); }