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);
 

Reply via email to