This is an automated email from the ASF dual-hosted git repository.
maplefu pushed a commit to branch unstable
in repository https://gitbox.apache.org/repos/asf/kvrocks.git
The following commit(s) were added to refs/heads/unstable by this push:
new e95e6f75 Making RedisBitmapTest also tests Bitmap String (#2075)
e95e6f75 is described below
commit e95e6f75b6f2eaa6568ad52bf0c12ee1329bc90e
Author: mwish <[email protected]>
AuthorDate: Wed Jan 31 15:11:23 2024 +0800
Making RedisBitmapTest also tests Bitmap String (#2075)
Co-authored-by: hulk <[email protected]>
---
src/types/redis_bitmap.cc | 7 +++-
src/types/redis_bitmap_string.cc | 8 ++---
tests/cppunit/test_base.h | 13 +++++--
tests/cppunit/types/bitmap_test.cc | 73 +++++++++++++++++++++++++++-----------
4 files changed, 70 insertions(+), 31 deletions(-)
diff --git a/src/types/redis_bitmap.cc b/src/types/redis_bitmap.cc
index 60569a9f..9fc93eb8 100644
--- a/src/types/redis_bitmap.cc
+++ b/src/types/redis_bitmap.cc
@@ -82,7 +82,7 @@ rocksdb::Status Bitmap::GetBit(const Slice &user_key,
uint32_t offset, bool *bit
rocksdb::ReadOptions read_options;
read_options.snapshot = ss.GetSnapShot();
uint32_t index = (offset / kBitmapSegmentBits) * kBitmapSegmentBytes;
- std::string value;
+ rocksdb::PinnableSlice value;
std::string sub_key =
InternalKey(ns_key, std::to_string(index), metadata.version,
storage_->IsSlotIdEncoded()).Encode();
s = storage_->Get(read_options, sub_key, &value);
@@ -219,6 +219,11 @@ rocksdb::Status Bitmap::BitCount(const Slice &user_key,
int64_t start, int64_t s
rocksdb::Status s = GetMetadata(ns_key, &metadata, &raw_value);
if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s;
+ /* Convert negative indexes */
+ if (start < 0 && stop < 0 && start > stop) {
+ return rocksdb::Status::OK();
+ }
+
if (metadata.Type() == kRedisString) {
redis::BitmapString bitmap_string_db(storage_, namespace_);
return bitmap_string_db.BitCount(raw_value, start, stop, cnt);
diff --git a/src/types/redis_bitmap_string.cc b/src/types/redis_bitmap_string.cc
index 228ce7e9..24befb54 100644
--- a/src/types/redis_bitmap_string.cc
+++ b/src/types/redis_bitmap_string.cc
@@ -32,7 +32,7 @@
namespace redis {
rocksdb::Status BitmapString::GetBit(const std::string &raw_value, uint32_t
offset, bool *bit) {
- auto string_value =
raw_value.substr(Metadata::GetOffsetAfterExpire(raw_value[0]));
+ std::string_view string_value =
std::string_view{raw_value}.substr(Metadata::GetOffsetAfterExpire(raw_value[0]));
uint32_t byte_index = offset >> 3;
uint32_t bit_val = 0;
uint32_t bit_offset = 7 - (offset & 0x7);
@@ -71,10 +71,6 @@ rocksdb::Status BitmapString::SetBit(const Slice &ns_key,
std::string *raw_value
rocksdb::Status BitmapString::BitCount(const std::string &raw_value, int64_t
start, int64_t stop, uint32_t *cnt) {
*cnt = 0;
std::string_view string_value =
std::string_view{raw_value}.substr(Metadata::GetOffsetAfterExpire(raw_value[0]));
- /* Convert negative indexes */
- if (start < 0 && stop < 0 && start > stop) {
- return rocksdb::Status::OK();
- }
auto strlen = static_cast<int64_t>(string_value.size());
std::tie(start, stop) = NormalizeRange(start, stop, strlen);
@@ -89,7 +85,7 @@ rocksdb::Status BitmapString::BitCount(const std::string
&raw_value, int64_t sta
rocksdb::Status BitmapString::BitPos(const std::string &raw_value, bool bit,
int64_t start, int64_t stop,
bool stop_given, int64_t *pos) {
- auto string_value =
raw_value.substr(Metadata::GetOffsetAfterExpire(raw_value[0]));
+ std::string_view string_value =
std::string_view{raw_value}.substr(Metadata::GetOffsetAfterExpire(raw_value[0]));
auto strlen = static_cast<int64_t>(string_value.size());
/* Convert negative and out-of-bound indexes */
std::tie(start, stop) = NormalizeRange(start, stop, strlen);
diff --git a/tests/cppunit/test_base.h b/tests/cppunit/test_base.h
index 6d9d6a39..16b7837b 100644
--- a/tests/cppunit/test_base.h
+++ b/tests/cppunit/test_base.h
@@ -28,9 +28,13 @@
#include "storage/redis_db.h"
#include "types/redis_hash.h"
-class TestBase : public testing::Test { // NOLINT
+class TestFixture { // NOLINT
+ public:
+ TestFixture(TestFixture &&) = delete;
+ TestFixture(const TestFixture &) = delete;
+
protected:
- explicit TestBase() {
+ explicit TestFixture() {
const char *path = "test.conf";
unlink(path);
std::ofstream output_file(path, std::ios::out);
@@ -48,7 +52,7 @@ class TestBase : public testing::Test { // NOLINT
assert(s.IsOK());
}
}
- ~TestBase() override {
+ ~TestFixture() {
storage_.reset();
std::error_code ec;
@@ -66,4 +70,7 @@ class TestBase : public testing::Test { // NOLINT
std::vector<Slice> fields_;
std::vector<Slice> values_;
};
+
+class TestBase : public TestFixture, public ::testing::Test {};
+
#endif // KVROCKS_TEST_BASE_H
diff --git a/tests/cppunit/types/bitmap_test.cc
b/tests/cppunit/types/bitmap_test.cc
index 9bb97381..7c6b64f0 100644
--- a/tests/cppunit/types/bitmap_test.cc
+++ b/tests/cppunit/types/bitmap_test.cc
@@ -26,7 +26,7 @@
#include "types/redis_bitmap.h"
#include "types/redis_string.h"
-class RedisBitmapTest : public TestBase {
+class RedisBitmapTest : public TestFixture, public
::testing::TestWithParam<bool> {
protected:
explicit RedisBitmapTest() {
bitmap_ = std::make_unique<redis::Bitmap>(storage_.get(), "bitmap_ns");
@@ -34,14 +34,25 @@ class RedisBitmapTest : public TestBase {
}
~RedisBitmapTest() override = default;
- void SetUp() override { key_ = "test_bitmap_key"; }
- void TearDown() override {}
+ void SetUp() override {
+ key_ = "test_bitmap_key";
+ if (bool use_bitmap = GetParam(); !use_bitmap) {
+ // Set an empty string.
+ string_->Set(key_, "");
+ }
+ }
+ void TearDown() override {
+ [[maybe_unused]] auto s = bitmap_->Del(key_);
+ s = string_->Del(key_);
+ }
std::unique_ptr<redis::Bitmap> bitmap_;
std::unique_ptr<redis::String> string_;
};
-TEST_F(RedisBitmapTest, GetAndSetBit) {
+INSTANTIATE_TEST_SUITE_P(UseBitmap, RedisBitmapTest, testing::Values(true,
false));
+
+TEST_P(RedisBitmapTest, GetAndSetBit) {
uint32_t offsets[] = {0, 123, 1024 * 8, 1024 * 8 + 1, 3 * 1024 * 8, 3 * 1024
* 8 + 1};
for (const auto &offset : offsets) {
bool bit = false;
@@ -54,7 +65,7 @@ TEST_F(RedisBitmapTest, GetAndSetBit) {
auto s = bitmap_->Del(key_);
}
-TEST_F(RedisBitmapTest, BitCount) {
+TEST_P(RedisBitmapTest, BitCount) {
uint32_t offsets[] = {0, 123, 1024 * 8, 1024 * 8 + 1, 3 * 1024 * 8, 3 * 1024
* 8 + 1};
for (const auto &offset : offsets) {
bool bit = false;
@@ -68,7 +79,7 @@ TEST_F(RedisBitmapTest, BitCount) {
auto s = bitmap_->Del(key_);
}
-TEST_F(RedisBitmapTest, BitCountNegative) {
+TEST_P(RedisBitmapTest, BitCountNegative) {
{
bool bit = false;
bitmap_->SetBit(key_, 0, true, &bit);
@@ -113,19 +124,36 @@ TEST_F(RedisBitmapTest, BitCountNegative) {
auto s = bitmap_->Del(key_);
}
-TEST_F(RedisBitmapTest, BitPosClearBit) {
+TEST_P(RedisBitmapTest, BitPosClearBit) {
int64_t pos = 0;
bool old_bit = false;
+ bool use_bitmap = GetParam();
for (int i = 0; i < 1024 + 16; i++) {
- bitmap_->BitPos(key_, false, 0, -1, true, &pos);
- EXPECT_EQ(pos, i);
+ /// ```
+ /// redis> set k1 ""
+ /// "OK"
+ /// redis> bitpos k1 0
+ /// (integer) -1
+ /// redis> bitpos k2 0
+ /// (integer) 0
+ /// ```
+ ///
+ /// String will set a empty string value when initializing, so, when first
+ /// querying, it should return -1.
+ bitmap_->BitPos(key_, false, 0, -1, /*stop_given=*/false, &pos);
+ if (i == 0 && !use_bitmap) {
+ EXPECT_EQ(pos, -1);
+ } else {
+ EXPECT_EQ(pos, i);
+ }
+
bitmap_->SetBit(key_, i, true, &old_bit);
EXPECT_FALSE(old_bit);
}
auto s = bitmap_->Del(key_);
}
-TEST_F(RedisBitmapTest, BitPosSetBit) {
+TEST_P(RedisBitmapTest, BitPosSetBit) {
uint32_t offsets[] = {0, 123, 1024 * 8, 1024 * 8 + 16, 3 * 1024 * 8, 3 *
1024 * 8 + 16};
for (const auto &offset : offsets) {
bool bit = false;
@@ -140,7 +168,7 @@ TEST_F(RedisBitmapTest, BitPosSetBit) {
auto s = bitmap_->Del(key_);
}
-TEST_F(RedisBitmapTest, BitPosNegative) {
+TEST_P(RedisBitmapTest, BitPosNegative) {
{
bool bit = false;
bitmap_->SetBit(key_, 8 * 1024 - 1, true, &bit);
@@ -166,7 +194,7 @@ TEST_F(RedisBitmapTest, BitPosNegative) {
auto s = bitmap_->Del(key_);
}
-TEST_F(RedisBitmapTest, BitfieldGetSetTest) {
+TEST_P(RedisBitmapTest, BitfieldGetSetTest) {
constexpr uint32_t magic = 0xdeadbeef;
std::vector<std::optional<BitfieldValue>> rets;
@@ -196,7 +224,7 @@ TEST_F(RedisBitmapTest, BitfieldGetSetTest) {
auto s = bitmap_->Del(key_);
}
-TEST_F(RedisBitmapTest, UnsignedBitfieldTest) {
+TEST_P(RedisBitmapTest, UnsignedBitfieldTest) {
constexpr uint8_t bits = 5;
static_assert(bits < 64);
constexpr uint64_t max = (uint64_t(1) << bits) - 1;
@@ -225,7 +253,7 @@ TEST_F(RedisBitmapTest, UnsignedBitfieldTest) {
auto s = bitmap_->Del(key_);
}
-TEST_F(RedisBitmapTest, SignedBitfieldTest) {
+TEST_P(RedisBitmapTest, SignedBitfieldTest) {
constexpr uint8_t bits = 10;
constexpr int64_t max = (uint64_t(1) << (bits - 1)) - 1;
constexpr int64_t min = -max - 1;
@@ -253,7 +281,7 @@ TEST_F(RedisBitmapTest, SignedBitfieldTest) {
auto s = bitmap_->Del(key_);
}
-TEST_F(RedisBitmapTest, SignedBitfieldWrapSetTest) {
+TEST_P(RedisBitmapTest, SignedBitfieldWrapSetTest) {
constexpr uint8_t bits = 6;
constexpr int64_t max = (int64_t(1) << (bits - 1)) - 1;
constexpr int64_t min = -max - 1;
@@ -288,7 +316,7 @@ TEST_F(RedisBitmapTest, SignedBitfieldWrapSetTest) {
auto s = bitmap_->Del(key_);
}
-TEST_F(RedisBitmapTest, UnsignedBitfieldWrapSetTest) {
+TEST_P(RedisBitmapTest, UnsignedBitfieldWrapSetTest) {
constexpr uint8_t bits = 6;
static_assert(bits < 64);
constexpr uint64_t max = (uint64_t(1) << bits) - 1;
@@ -323,7 +351,7 @@ TEST_F(RedisBitmapTest, UnsignedBitfieldWrapSetTest) {
auto s = bitmap_->Del(key_);
}
-TEST_F(RedisBitmapTest, SignedBitfieldSatSetTest) {
+TEST_P(RedisBitmapTest, SignedBitfieldSatSetTest) {
constexpr uint8_t bits = 6;
constexpr int64_t max = (int64_t(1) << (bits - 1)) - 1;
@@ -359,7 +387,7 @@ TEST_F(RedisBitmapTest, SignedBitfieldSatSetTest) {
auto s = bitmap_->Del(key_);
}
-TEST_F(RedisBitmapTest, UnsignedBitfieldSatSetTest) {
+TEST_P(RedisBitmapTest, UnsignedBitfieldSatSetTest) {
constexpr uint8_t bits = 6;
static_assert(bits < 64);
constexpr uint64_t max = (uint64_t(1) << bits) - 1;
@@ -396,7 +424,7 @@ TEST_F(RedisBitmapTest, UnsignedBitfieldSatSetTest) {
auto s = bitmap_->Del(key_);
}
-TEST_F(RedisBitmapTest, SignedBitfieldFailSetTest) {
+TEST_P(RedisBitmapTest, SignedBitfieldFailSetTest) {
constexpr uint8_t bits = 5;
constexpr int64_t max = (int64_t(1) << (bits - 1)) - 1;
@@ -432,7 +460,7 @@ TEST_F(RedisBitmapTest, SignedBitfieldFailSetTest) {
auto s = bitmap_->Del(key_);
}
-TEST_F(RedisBitmapTest, UnsignedBitfieldFailSetTest) {
+TEST_P(RedisBitmapTest, UnsignedBitfieldFailSetTest) {
constexpr uint8_t bits = 5;
constexpr int64_t max = (int64_t(1) << bits) - 1;
@@ -468,7 +496,10 @@ TEST_F(RedisBitmapTest, UnsignedBitfieldFailSetTest) {
auto s = bitmap_->Del(key_);
}
-TEST_F(RedisBitmapTest, BitfieldStringGetSetTest) {
+TEST_P(RedisBitmapTest, BitfieldStringGetSetTest) {
+ if (bool use_bitmap = GetParam(); use_bitmap) {
+ GTEST_SKIP() << "skip bitmap test for BitfieldStringGetSetTest";
+ }
std::string str = "dan yuan ren chang jiu, qian li gong chan juan.";
string_->Set(key_, str);