/** * Copyright (c) 2023 OceanBase * OceanBase CE is licensed under Mulan PubL v2. * You can use this software according to the terms and conditions of the Mulan PubL v2. * You may obtain a copy of Mulan PubL v2 at: * http://license.coscl.org.cn/MulanPubL-2.0 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PubL v2 for more details. */ #include #define private public #include "lib/roaringbitmap/ob_roaringbitmap.h" #include "lib/roaringbitmap/ob_rb_utils.h" #include "lib/utility/ob_macro_utils.h" #undef private #include #include #include #include namespace oceanbase { namespace common { class TestRoaringBitmap : public ::testing::Test { public: TestRoaringBitmap() {} ~TestRoaringBitmap() {} virtual void SetUp() {} virtual void TearDown() {} static void SetUpTestCase() {} static void TearDownTestCase() {} private: // disallow copy DISALLOW_COPY_AND_ASSIGN(TestRoaringBitmap); }; TEST_F(TestRoaringBitmap, serialize_deserialize) { ObArenaAllocator allocator(ObModIds::TEST); ModulePageAllocator page_allocator_(allocator, common::ObModIds::OB_MODULE_PAGE_ALLOCATOR); ObRoaringBitmap *rb = OB_NEWx(ObRoaringBitmap, &allocator, (&allocator)); ObRoaringBitmap *rb_64 = OB_NEWx(ObRoaringBitmap, &allocator, (&allocator)); // EMPTY Type ASSERT_EQ(rb->get_version(), BITMAP_VESION_1); ASSERT_EQ(rb->get_type(), ObRbType::EMPTY); ASSERT_EQ(rb->get_cardinality(), 0); ObString bin_empty; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_serialize(allocator, bin_empty, rb)); ASSERT_EQ(ObRbBinType::EMPTY, static_cast(*(bin_empty.ptr() + 1))); ObRoaringBitmap *rb_empty; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_deserialize(allocator, bin_empty, rb_empty)); ASSERT_EQ(rb->get_version(), rb_empty->get_version()); ASSERT_EQ(rb->get_type(), rb_empty->get_type()); ASSERT_EQ(rb->get_cardinality(), rb_empty->get_cardinality()); // SINGLE_32 Type ASSERT_EQ(OB_SUCCESS, rb->value_add(100)); ASSERT_EQ(rb->get_type(), ObRbType::SINGLE); ASSERT_EQ(rb->get_cardinality(), 1); ASSERT_TRUE(rb->is_contains(100)); ObString bin_single; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_serialize(allocator, bin_single, rb)); ASSERT_EQ(ObRbBinType::SINGLE_32, static_cast(*(bin_single.ptr() + 1))); ObRoaringBitmap *rb_single; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_deserialize(allocator, bin_single, rb_single)); ASSERT_EQ(rb->get_version(), rb_single->get_version()); ASSERT_EQ(rb->get_type(), rb_single->get_type()); ASSERT_EQ(rb->get_cardinality(), rb_single->get_cardinality()); ASSERT_TRUE(rb_single->is_contains(100)); // SET_32 Type ASSERT_EQ(OB_SUCCESS, rb->value_add(200)); ASSERT_EQ(rb->get_type(), ObRbType::SET); ASSERT_EQ(rb->get_cardinality(), 2); ASSERT_TRUE(rb->is_contains(100)); ASSERT_TRUE(rb->is_contains(200)); ObString bin_set; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_serialize(allocator, bin_set, rb)); ASSERT_EQ(ObRbBinType::SET_32, static_cast(*(bin_set.ptr() + 1))); ObRoaringBitmap *rb_set; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_deserialize(allocator, bin_set, rb_set)); ASSERT_EQ(rb->get_version(), rb_set->get_version()); ASSERT_EQ(rb->get_type(), rb_set->get_type()); ASSERT_EQ(rb->get_cardinality(), rb_set->get_cardinality()); ASSERT_TRUE(rb_set->is_contains(100)); ASSERT_TRUE(rb_set->is_contains(200)); // BITMAP_32 Type for (int i = 0; i < MAX_BITMAP_SET_VALUES; i++) { ASSERT_EQ(OB_SUCCESS, rb->value_add(300 + i)); } ASSERT_EQ(rb->get_type(), ObRbType::BITMAP); ASSERT_EQ(rb->get_cardinality(), 34); for (int i = 0; i < MAX_BITMAP_SET_VALUES; i++) { ASSERT_TRUE(rb->is_contains(300 + i)); } ObString bin_bitmap; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_serialize(allocator, bin_bitmap, rb)); ASSERT_EQ(ObRbBinType::BITMAP_64, static_cast(*(bin_bitmap.ptr() + 1))); ObRoaringBitmap *rb_bitmap; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_deserialize(allocator, bin_bitmap, rb_bitmap)); ASSERT_EQ(rb->get_version(), rb_bitmap->get_version()); ASSERT_EQ(rb->get_type(), rb_bitmap->get_type()); ASSERT_EQ(rb->get_cardinality(), rb_bitmap->get_cardinality()); for (int i = 0; i < MAX_BITMAP_SET_VALUES; i++) { ASSERT_TRUE(rb_bitmap->is_contains(300 + i)); } // SINGLE_64 Type ASSERT_EQ(OB_SUCCESS, rb_64->value_add(4294967295 + 100)); ASSERT_EQ(rb_64->get_type(), ObRbType::SINGLE); ASSERT_EQ(rb_64->get_cardinality(), 1); ASSERT_TRUE(rb_64->is_contains(4294967295 + 100)); ObString bin_single_64; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_serialize(allocator, bin_single_64, rb_64)); ASSERT_EQ(ObRbBinType::SINGLE_64, static_cast(*(bin_single_64.ptr() + 1))); ObRoaringBitmap *rb_single_64; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_deserialize(allocator, bin_single_64, rb_single_64)); ASSERT_EQ(rb_64->get_version(), rb_single_64->get_version()); ASSERT_EQ(rb_64->get_type(), rb_single_64->get_type()); ASSERT_EQ(rb_64->get_cardinality(), rb_single_64->get_cardinality()); ASSERT_TRUE(rb_single_64->is_contains(4294967295 + 100)); // SET_64 Type ASSERT_EQ(OB_SUCCESS, rb_64->value_add(200)); ASSERT_EQ(rb_64->get_type(), ObRbType::SET); ASSERT_EQ(rb_64->get_cardinality(), 2); ASSERT_TRUE(rb_64->is_contains(4294967295 + 100)); ASSERT_TRUE(rb_64->is_contains(200)); ObString bin_set_64; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_serialize(allocator, bin_set_64, rb_64)); ASSERT_EQ(ObRbBinType::SET_64, static_cast(*(bin_set_64.ptr() + 1))); ObRoaringBitmap *rb_set_64; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_deserialize(allocator, bin_set_64, rb_set_64)); ASSERT_EQ(rb_64->get_version(), rb_set_64->get_version()); ASSERT_EQ(rb_64->get_type(), rb_set_64->get_type()); ASSERT_EQ(rb_64->get_cardinality(), rb_set_64->get_cardinality()); ASSERT_TRUE(rb_set_64->is_contains(4294967295 + 100)); ASSERT_TRUE(rb_set_64->is_contains(200)); // BITMAP_64 Type for (int i = 0; i < MAX_BITMAP_SET_VALUES; i++) { ASSERT_EQ(OB_SUCCESS, rb_64->value_add(i * 4294967295 + i)); } ASSERT_EQ(rb_64->get_type(), ObRbType::BITMAP); ASSERT_EQ(rb_64->get_cardinality(), 34); for (int i = 0; i < MAX_BITMAP_SET_VALUES; i++) { ASSERT_TRUE(rb_64->is_contains(i * 4294967295 + i)); } ObString bin_bitmap_64; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_serialize(allocator, bin_bitmap_64, rb_64)); ASSERT_EQ(ObRbBinType::BITMAP_64, static_cast(*(bin_bitmap_64.ptr() + 1))); ObRoaringBitmap *rb_bitmap_64; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_deserialize(allocator, bin_bitmap_64, rb_bitmap_64)); ASSERT_EQ(rb_64->get_version(), rb_bitmap_64->get_version()); ASSERT_EQ(rb_64->get_type(), rb_bitmap_64->get_type()); ASSERT_EQ(rb_64->get_cardinality(), rb_bitmap_64->get_cardinality()); for (int i = 0; i < MAX_BITMAP_SET_VALUES; i++) { ASSERT_TRUE(rb_bitmap_64->is_contains(i * 4294967295 + i)); } } TEST_F(TestRoaringBitmap, optimize) { ObArenaAllocator allocator(ObModIds::TEST); ModulePageAllocator page_allocator_(allocator, common::ObModIds::OB_MODULE_PAGE_ALLOCATOR); ObRoaringBitmap *rb = OB_NEWx(ObRoaringBitmap, &allocator, (&allocator)); // add 33 value, remain 33 value for (int i = 0; i < MAX_BITMAP_SET_VALUES + 1; i++) { ASSERT_EQ(OB_SUCCESS, rb->value_add(300 + i)); } ASSERT_EQ(rb->get_type(), ObRbType::BITMAP); ASSERT_EQ(rb->get_cardinality(), 33); // remove 32 value, remain 32 value ASSERT_EQ(rb->value_remove(300), OB_SUCCESS); ASSERT_EQ(rb->get_cardinality(), 32); ASSERT_FALSE(rb->is_contains(300)); rb->optimize(); ASSERT_EQ(rb->get_type(), ObRbType::SET); // remove 1 value, remain 33 value ASSERT_EQ(rb->value_add(300), OB_SUCCESS); ASSERT_EQ(rb->get_cardinality(), 33); ASSERT_EQ(rb->get_type(), ObRbType::BITMAP); // remove 32 value, remain 1 value for (int i = 0; i < MAX_BITMAP_SET_VALUES; i++) { ASSERT_EQ(rb->value_remove(300 + i), OB_SUCCESS); } ASSERT_EQ(rb->get_type(), ObRbType::BITMAP); ASSERT_EQ(rb->get_cardinality(), 1); rb->optimize(); ASSERT_EQ(rb->get_type(), ObRbType::SINGLE); ASSERT_EQ(rb->get_cardinality(), 1); // remove 1 value, remain 0 value ASSERT_EQ(rb->value_remove(300 + 32), OB_SUCCESS); ASSERT_EQ(rb->get_type(), ObRbType::EMPTY); ASSERT_EQ(rb->get_cardinality(), 0); // add 32 value, remain 32 value for (int i = 0; i < MAX_BITMAP_SET_VALUES; i++) { ASSERT_EQ(rb->value_add(i), OB_SUCCESS); } ASSERT_EQ(rb->get_type(), ObRbType::SET); ASSERT_EQ(rb->get_cardinality(), 32); // remove 32 value, remain 0 value for (int i = 0; i < MAX_BITMAP_SET_VALUES; i++) { ASSERT_EQ(rb->value_remove(i), OB_SUCCESS); } ASSERT_EQ(rb->get_type(), ObRbType::SET); ASSERT_EQ(rb->get_cardinality(), 0); // add 33 value, remain 33 value for (int i = 0; i < MAX_BITMAP_SET_VALUES + 1; i++) { ASSERT_EQ(rb->value_add(300 + i), OB_SUCCESS); } ASSERT_EQ(rb->get_type(), ObRbType::BITMAP); ASSERT_EQ(rb->get_cardinality(), 33); // remove 33 value, remain 0 value for (int i = 0; i < MAX_BITMAP_SET_VALUES + 1; i++) { ASSERT_EQ(rb->value_remove(300 + i), OB_SUCCESS); } ASSERT_EQ(rb->get_type(), ObRbType::BITMAP); ASSERT_EQ(rb->get_cardinality(), 0); rb->optimize(); ASSERT_EQ(rb->get_type(), ObRbType::EMPTY); ASSERT_EQ(rb->get_cardinality(), 0); // add 2 value, remain 2 value for (int i = 0; i < 2; i++) { ASSERT_EQ(rb->value_add(300 + i), OB_SUCCESS); } ASSERT_EQ(rb->get_type(), ObRbType::SET); ASSERT_EQ(rb->get_cardinality(), 2); // remove 1 value, remain 1 value ASSERT_EQ(rb->value_remove(300), OB_SUCCESS); ASSERT_EQ(rb->get_type(), ObRbType::SET); ASSERT_EQ(rb->get_cardinality(), 1); rb->optimize(); ASSERT_EQ(rb->get_type(), ObRbType::SINGLE); ASSERT_EQ(rb->get_cardinality(), 1); } TEST_F(TestRoaringBitmap, to_roaring_bin) { ObArenaAllocator allocator(ObModIds::TEST); ModulePageAllocator page_allocator_(allocator, common::ObModIds::OB_MODULE_PAGE_ALLOCATOR); ObRoaringBitmap *rb = OB_NEWx(ObRoaringBitmap, &allocator, (&allocator)); ObRoaringBitmap *rb64 = OB_NEWx(ObRoaringBitmap, &allocator, (&allocator)); // EMPTY ObString bin_empty; ObString roaring_bin_empty; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_serialize(allocator, bin_empty, rb)); ASSERT_EQ(OB_SUCCESS, ObRbUtils::binary_format_convert(allocator, bin_empty, roaring_bin_empty)); ObRbBinType bin_type_empty; ASSERT_EQ(OB_SUCCESS, ObRbUtils::get_bin_type(roaring_bin_empty, bin_type_empty)); ASSERT_EQ(ObRbBinType::BITMAP_32, bin_type_empty); ObRoaringBitmap *rb_roaring_empty; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_deserialize(allocator, roaring_bin_empty, rb_roaring_empty)); ASSERT_EQ(rb_roaring_empty->get_version(), 1); ASSERT_EQ(rb_roaring_empty->get_type(), ObRbType::BITMAP); ASSERT_EQ(rb_roaring_empty->get_cardinality(), 0); // SINGLE_32 ASSERT_EQ(OB_SUCCESS, rb->value_add(100)); ObString bin_single; ObString roaring_bin_single; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_serialize(allocator, bin_single, rb)); ASSERT_EQ(OB_SUCCESS, ObRbUtils::binary_format_convert(allocator, bin_single, roaring_bin_single)); ObRbBinType bin_type_single; ASSERT_EQ(OB_SUCCESS, ObRbUtils::get_bin_type(roaring_bin_single, bin_type_single)); ASSERT_EQ(ObRbBinType::BITMAP_32, bin_type_single); ObRoaringBitmap *rb_roaring_single; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_deserialize(allocator, roaring_bin_single, rb_roaring_single)); ASSERT_EQ(rb_roaring_single->get_version(), 1); ASSERT_EQ(rb_roaring_single->get_type(), ObRbType::BITMAP); ASSERT_EQ(rb_roaring_single->get_cardinality(), 1); ASSERT_TRUE(rb_roaring_single->is_contains(100)); // SET_32 ASSERT_EQ(OB_SUCCESS, rb->value_add(101)); ObString bin_set; ObString roaring_bin_set; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_serialize(allocator, bin_set, rb)); ASSERT_EQ(OB_SUCCESS, ObRbUtils::binary_format_convert(allocator, bin_set, roaring_bin_set)); ObRbBinType bin_type_set; ASSERT_EQ(OB_SUCCESS, ObRbUtils::get_bin_type(roaring_bin_set, bin_type_set)); ASSERT_EQ(ObRbBinType::BITMAP_32, bin_type_set); ObRoaringBitmap *rb_roaring_set; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_deserialize(allocator, roaring_bin_set, rb_roaring_set)); ASSERT_EQ(rb_roaring_set->get_version(), 1); ASSERT_EQ(rb_roaring_set->get_type(), ObRbType::BITMAP); ASSERT_EQ(rb_roaring_set->get_cardinality(), 2); ASSERT_TRUE(rb_roaring_set->is_contains(100)); ASSERT_TRUE(rb_roaring_set->is_contains(101)); // BITMAP_32 for (int i = 0; i < MAX_BITMAP_SET_VALUES; i++) { ASSERT_EQ(OB_SUCCESS, rb->value_add(300 + i)); } ObString bin_bitmap; ObString roaring_bin_bitmap; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_serialize(allocator, bin_bitmap, rb)); ASSERT_EQ(OB_SUCCESS, ObRbUtils::binary_format_convert(allocator, bin_bitmap, roaring_bin_bitmap)); ObRbBinType bin_type_bitmap; ASSERT_EQ(OB_SUCCESS, ObRbUtils::get_bin_type(roaring_bin_bitmap, bin_type_bitmap)); ASSERT_EQ(ObRbBinType::BITMAP_32, bin_type_bitmap); ObRoaringBitmap *rb_roaring_bitmap; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_deserialize(allocator, roaring_bin_bitmap, rb_roaring_bitmap)); ASSERT_EQ(rb_roaring_bitmap->get_version(), 1); ASSERT_EQ(rb_roaring_bitmap->get_type(), ObRbType::BITMAP); ASSERT_EQ(rb_roaring_bitmap->get_cardinality(), 34); for (int i = 0; i < MAX_BITMAP_SET_VALUES; i++) { ASSERT_TRUE(rb_roaring_bitmap->is_contains(300 + i)); } // SINGLE_64 ASSERT_EQ(OB_SUCCESS, rb64->value_add(4294967295 + 100)); ObString bin_single64; ObString roaring_bin_single64; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_serialize(allocator, bin_single64, rb64)); ASSERT_EQ(OB_SUCCESS, ObRbUtils::binary_format_convert(allocator, bin_single64, roaring_bin_single64)); ObRbBinType bin_type_single64; ASSERT_EQ(OB_SUCCESS, ObRbUtils::get_bin_type(roaring_bin_single64, bin_type_single64)); ASSERT_EQ(ObRbBinType::BITMAP_64, bin_type_single64); ObRoaringBitmap *rb_roaring_single64; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_deserialize(allocator, roaring_bin_single64, rb_roaring_single64)); ASSERT_EQ(rb_roaring_single64->get_version(), 1); ASSERT_EQ(rb_roaring_single64->get_type(), ObRbType::BITMAP); ASSERT_EQ(rb_roaring_single64->get_cardinality(), 1); ASSERT_TRUE(rb_roaring_single64->is_contains(4294967295 + 100)); // SET_64 ASSERT_EQ(OB_SUCCESS, rb64->value_add(4294967295 + 101)); ObString bin_set64; ObString roaring_bin_set64; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_serialize(allocator, bin_set64, rb64)); ASSERT_EQ(OB_SUCCESS, ObRbUtils::binary_format_convert(allocator, bin_set64, roaring_bin_set64)); ObRbBinType bin_type_set64; ASSERT_EQ(OB_SUCCESS, ObRbUtils::get_bin_type(roaring_bin_set64, bin_type_set64)); ASSERT_EQ(ObRbBinType::BITMAP_64, bin_type_set64); ObRoaringBitmap *rb_roaring_set64; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_deserialize(allocator, roaring_bin_set64, rb_roaring_set64)); ASSERT_EQ(rb_roaring_set64->get_version(), 1); ASSERT_EQ(rb_roaring_set64->get_type(), ObRbType::BITMAP); ASSERT_EQ(rb_roaring_set64->get_cardinality(), 2); ASSERT_TRUE(rb_roaring_set64->is_contains(4294967295 + 100)); ASSERT_TRUE(rb_roaring_set64->is_contains(4294967295 + 101)); // BITMAP_64 for (int i = 0; i < MAX_BITMAP_SET_VALUES; i++) { ASSERT_EQ(OB_SUCCESS, rb64->value_add(4294967295 + 300 + i)); } ObString bin_bitmap64; ObString roaring_bin_bitmap64; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_serialize(allocator, bin_bitmap64, rb64)); ASSERT_EQ(OB_SUCCESS, ObRbUtils::binary_format_convert(allocator, bin_bitmap64, roaring_bin_bitmap64)); ObRbBinType bin_type_bitmap64; ASSERT_EQ(OB_SUCCESS, ObRbUtils::get_bin_type(roaring_bin_bitmap64, bin_type_bitmap64)); ASSERT_EQ(ObRbBinType::BITMAP_64, bin_type_bitmap64); ObRoaringBitmap *rb_roaring_bitmap64; ASSERT_EQ(OB_SUCCESS, ObRbUtils::rb_deserialize(allocator, roaring_bin_bitmap64, rb_roaring_bitmap64)); ASSERT_EQ(rb_roaring_bitmap64->get_version(), 1); ASSERT_EQ(rb_roaring_bitmap64->get_type(), ObRbType::BITMAP); ASSERT_EQ(rb_roaring_bitmap64->get_cardinality(), 34); for (int i = 0; i < MAX_BITMAP_SET_VALUES; i++) { ASSERT_TRUE(rb_roaring_bitmap64->is_contains(4294967295 + 300 + i)); } } } // namespace common } // namespace oceanbase int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); // system("rm -f test_geo_tree.log"); // OB_LOGGER.set_file_name("test_geo_tree.log"); OB_LOGGER.set_log_level("DEBUG"); return RUN_ALL_TESTS(); }