| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| #include "util/bitmap_value.h" |
| |
| #include <gtest/gtest-message.h> |
| #include <gtest/gtest-test-part.h> |
| #include <roaring/roaring.h> |
| |
| #include <cstdint> |
| #include <string> |
| |
| #include "gtest/gtest.h" |
| #include "gtest/gtest_pred_impl.h" |
| #include "util/coding.h" |
| |
| namespace doris { |
| using roaring::Roaring; |
| |
| TEST(BitmapValueTest, BitmapTypeCode_validate) { |
| EXPECT_EQ(BitmapTypeCode::validate(BitmapTypeCode::TYPE_MAX + 1).code(), ErrorCode::CORRUPTION); |
| } |
| |
| TEST(BitmapValueTest, Roaring64Map_ctors) { |
| const std::vector<uint32_t> values({1, 3, 5, 7, 9, 2, 4, 6, 8, 1, 8, 9}); |
| detail::Roaring64Map roaring64_map(values.size(), values.data()); |
| EXPECT_EQ(roaring64_map.cardinality(), 9); |
| EXPECT_TRUE(roaring64_map.contains(uint32_t(1))); |
| EXPECT_TRUE(roaring64_map.contains(uint32_t(2))); |
| EXPECT_TRUE(roaring64_map.contains(uint32_t(9))); |
| EXPECT_FALSE(roaring64_map.contains(uint32_t(0))); |
| |
| const std::vector<uint64_t> values_long( |
| {1, 3, 5, 7, 9, 2, 4, 6, 8, 1, 8, std::numeric_limits<uint64_t>::max()}); |
| detail::Roaring64Map roaring64_map2(values_long.size(), values_long.data()); |
| EXPECT_EQ(roaring64_map.cardinality(), 9); |
| EXPECT_TRUE(roaring64_map2.contains(uint64_t(1))); |
| EXPECT_TRUE(roaring64_map2.contains(uint64_t(2))); |
| EXPECT_TRUE(roaring64_map2.contains(uint64_t(9))); |
| EXPECT_TRUE(roaring64_map2.contains(std::numeric_limits<uint64_t>::max())); |
| EXPECT_FALSE(roaring64_map2.contains(uint32_t(0))); |
| |
| auto roaring64_map_and = roaring64_map2 & roaring64_map; |
| EXPECT_EQ(roaring64_map_and.cardinality(), 9); |
| EXPECT_EQ(roaring64_map_and.cardinality(), roaring64_map2.andCardinality(roaring64_map)); |
| |
| auto roaring64_map_xor = roaring64_map2 ^ roaring64_map; |
| EXPECT_EQ(roaring64_map_xor.cardinality(), 1); |
| EXPECT_TRUE(roaring64_map_xor.contains(std::numeric_limits<uint64_t>::max())); |
| |
| roaring64_map_and.swap(roaring64_map_xor); |
| EXPECT_EQ(roaring64_map_and.cardinality(), 1); |
| EXPECT_EQ(roaring64_map_xor.cardinality(), 9); |
| |
| roaring::Roaring roaring32(values.size(), values.data()); |
| detail::Roaring64Map roaring64_map3(roaring32); |
| EXPECT_EQ(roaring64_map3.cardinality(), 9); |
| EXPECT_TRUE(roaring64_map3.contains(uint32_t(1))); |
| EXPECT_TRUE(roaring64_map3.contains(uint32_t(2))); |
| EXPECT_TRUE(roaring64_map3.contains(uint32_t(9))); |
| EXPECT_FALSE(roaring64_map3.contains(uint32_t(0))); |
| } |
| |
| TEST(BitmapValueTest, Roaring64Map_add_remove) { |
| detail::Roaring64Map roaring64_map; |
| const std::vector<uint32_t> values({1, 3, 5, 7, 9, 2, 4, 6, 8, 1, 8, 9}); |
| roaring64_map.addMany(values.size(), values.data()); |
| EXPECT_EQ(roaring64_map.cardinality(), 9); |
| |
| const std::vector<uint16_t> values_short({1, 3, 5, 7, 8, 9, 100}); |
| roaring64_map.addMany(values_short.size(), values_short.data()); |
| EXPECT_EQ(roaring64_map.cardinality(), 10); |
| |
| const std::vector<uint64_t> values_long( |
| {1, 3, 5, 7, 9, 2, 4, 6, 8, 1, 8, std::numeric_limits<uint64_t>::max()}); |
| roaring64_map.addMany(values_long.size(), values_long.data()); |
| EXPECT_EQ(roaring64_map.cardinality(), 11); |
| |
| roaring64_map.add(uint64_t(1000)); |
| EXPECT_TRUE(roaring64_map.contains(uint64_t(1000))); |
| EXPECT_EQ(roaring64_map.cardinality(), 12); |
| |
| roaring64_map.remove(uint32_t(8)); |
| EXPECT_FALSE(roaring64_map.contains(uint32_t(8))); |
| EXPECT_FALSE(roaring64_map.contains(uint64_t(8))); |
| |
| roaring64_map.remove(uint64_t(8)); |
| EXPECT_FALSE(roaring64_map.contains(uint64_t(8))); |
| } |
| |
| TEST(BitmapValueTest, Roaring64Map_cardinality) { |
| detail::Roaring64Map roaring64_map1, roaring64_map2; |
| |
| EXPECT_TRUE(roaring64_map1.isEmpty()); |
| EXPECT_FALSE(roaring64_map1.contains(std::numeric_limits<uint32_t>::max())); |
| EXPECT_FALSE(roaring64_map2.contains(std::numeric_limits<uint64_t>::max())); |
| EXPECT_EQ(roaring64_map1.minimum(), std::numeric_limits<uint64_t>::max()); |
| EXPECT_EQ(roaring64_map1.maximum(), std::numeric_limits<uint64_t>::min()); |
| |
| const std::vector<uint32_t> values1({0, 1, 2, 3, 4, 5, 6}); |
| const std::vector<uint32_t> values2({3, 4, 5, 6, 7, 8, 9}); |
| |
| roaring64_map1.addMany(values1.size(), values1.data()); |
| roaring64_map2.addMany(values2.size(), values2.data()); |
| |
| EXPECT_EQ(roaring64_map1.xorCardinality(roaring64_map2), 6); |
| EXPECT_EQ(roaring64_map1.orCardinality(roaring64_map2), 10); |
| EXPECT_EQ(roaring64_map1.andCardinality(roaring64_map2), 4); |
| } |
| |
| TEST(BitmapValueTest, Roaring64Map_operator_eq) { |
| detail::Roaring64Map roaring64_map1, roaring64_map2; |
| EXPECT_TRUE(roaring64_map1 == roaring64_map2); |
| |
| roaring64_map2.add(uint32_t(100)); |
| EXPECT_FALSE(roaring64_map1 == roaring64_map2); |
| |
| roaring64_map2.remove(uint32_t(100)); |
| EXPECT_TRUE(roaring64_map1 == roaring64_map2); |
| |
| roaring64_map1.add(uint32_t(100)); |
| EXPECT_FALSE(roaring64_map1 == roaring64_map2); |
| |
| roaring64_map2.add(uint32_t(100)); |
| EXPECT_TRUE(roaring64_map1 == roaring64_map2); |
| |
| roaring64_map2.remove(uint32_t(100)); |
| EXPECT_FALSE(roaring64_map1 == roaring64_map2); |
| |
| roaring64_map1.remove(uint32_t(100)); |
| EXPECT_TRUE(roaring64_map1 == roaring64_map2); |
| } |
| |
| TEST(BitmapValueTest, Roaring64Map_shrinkToFit) { |
| detail::Roaring64Map roaring64_map; |
| const std::vector<uint32_t> values({0, 1, 3, 4, 5, 7, 8}); |
| roaring64_map.addMany(values.size(), values.data()); |
| |
| EXPECT_EQ(roaring64_map.shrinkToFit(), 12); |
| |
| roaring64_map.add(std::numeric_limits<uint64_t>::max()); |
| EXPECT_EQ(roaring64_map.shrinkToFit(), 11); |
| |
| roaring64_map.remove(std::numeric_limits<uint64_t>::max()); |
| EXPECT_EQ(roaring64_map.shrinkToFit(), 88); |
| } |
| |
| TEST(BitmapValueTest, Roaring64Map_iterate) { |
| detail::Roaring64Map roaring64_map; |
| const std::vector<uint32_t> values({0, 1, 3, 4, 5, 7, 8}); |
| roaring64_map.addMany(values.size(), values.data()); |
| |
| std::vector<uint64_t> values2; |
| roaring64_map.iterate( |
| [](uint64_t low_bits, void* inner_iter_data) -> bool { |
| if (low_bits == 7) { |
| return false; |
| } |
| reinterpret_cast<std::vector<uint64_t>*>(inner_iter_data)->emplace_back(low_bits); |
| return true; |
| }, |
| &values2); |
| |
| EXPECT_EQ(std::find(values2.begin(), values2.end(), 7), values2.cend()); |
| } |
| |
| TEST(BitmapValueTest, Roaring64Map_write_read) { |
| detail::Roaring64Map roaring64_map; |
| |
| // empty bitmap |
| auto bytes = roaring64_map.getSizeInBytes(1); |
| std::unique_ptr<char[]> buffer(new char[bytes]); |
| |
| roaring64_map.write(buffer.get(), 1); |
| |
| detail::Roaring64Map bitmap_read = detail::Roaring64Map::read(buffer.get()); |
| |
| EXPECT_EQ(bitmap_read, roaring64_map); |
| |
| bytes = roaring64_map.getSizeInBytes(2); |
| buffer.reset(new char[bytes]); |
| |
| roaring64_map.write(buffer.get(), 2); |
| bitmap_read = detail::Roaring64Map::read(buffer.get()); |
| |
| EXPECT_EQ(bitmap_read, roaring64_map); |
| |
| const std::vector<uint32_t> values({0, 1, 3, 4, 5, 7, 8}); |
| roaring64_map.addMany(values.size(), values.data()); |
| |
| bytes = roaring64_map.getSizeInBytes(1); |
| buffer.reset(new char[bytes]); |
| |
| roaring64_map.write(buffer.get(), 1); |
| |
| bitmap_read = detail::Roaring64Map::read(buffer.get()); |
| |
| EXPECT_EQ(bitmap_read, roaring64_map); |
| |
| bytes = roaring64_map.getSizeInBytes(2); |
| buffer.reset(new char[bytes]); |
| |
| roaring64_map.write(buffer.get(), 2); |
| bitmap_read = detail::Roaring64Map::read(buffer.get()); |
| |
| EXPECT_EQ(bitmap_read, roaring64_map); |
| } |
| |
| TEST(BitmapValueTest, Roaring64Map_iterators) { |
| detail::Roaring64Map roaring64_map; |
| |
| auto begin = roaring64_map.begin(); |
| auto end = roaring64_map.end(); |
| |
| EXPECT_TRUE(begin == end); |
| EXPECT_FALSE(begin != end); |
| |
| const std::vector<uint64_t> values({0, 1, 2, 3, 4, 5, 6, 4294967297, 4294967298}); |
| roaring64_map.addMany(values.size(), values.data()); |
| |
| begin = roaring64_map.begin(); |
| end = roaring64_map.end(); |
| |
| EXPECT_FALSE(begin == end); |
| EXPECT_TRUE(begin != end); |
| |
| auto iter = roaring64_map.begin(); |
| while (iter != end) { |
| EXPECT_TRUE(iter != end); |
| ++iter; |
| } |
| |
| iter = roaring64_map.begin(); |
| while (iter != end) { |
| EXPECT_TRUE(iter != end); |
| iter++; |
| } |
| |
| iter = roaring64_map.begin(); |
| EXPECT_TRUE(iter.move(2)); |
| EXPECT_TRUE(iter.move(4294967296)); |
| EXPECT_FALSE(iter.move(4294967299)); |
| |
| iter = roaring64_map.begin(); |
| auto iter2 = roaring64_map.begin(); |
| iter.move(3); |
| iter2.move(3); |
| EXPECT_TRUE(iter == iter2); |
| } |
| |
| TEST(BitmapValueTest, set) { |
| config::enable_set_in_bitmap_value = false; |
| BitmapValue bitmap_value; |
| |
| bitmap_value.add(4294967297); |
| EXPECT_EQ(bitmap_value.get_type_code(), BitmapTypeCode::SINGLE64); |
| bitmap_value.reset(); |
| |
| bitmap_value.add(10); |
| EXPECT_EQ(bitmap_value.get_type_code(), BitmapTypeCode::SINGLE32); |
| |
| config::enable_set_in_bitmap_value = true; |
| bitmap_value.add(11); |
| |
| BitmapValue bitmap_value2(bitmap_value); |
| BitmapValue bitmap_value3(std::move(bitmap_value)); |
| |
| EXPECT_EQ(bitmap_value2.get_type_code(), BitmapTypeCode::SET); |
| EXPECT_EQ(bitmap_value3.get_type_code(), BitmapTypeCode::SET); |
| EXPECT_EQ(bitmap_value.get_type_code(), BitmapTypeCode::EMPTY); |
| |
| bitmap_value2 &= bitmap_value3; |
| EXPECT_EQ(bitmap_value2.cardinality(), bitmap_value3.cardinality()); |
| EXPECT_TRUE(bitmap_value.empty()); |
| |
| auto bitmap_value4 = std::move(bitmap_value3); |
| EXPECT_EQ(bitmap_value2.cardinality(), bitmap_value4.cardinality()); |
| |
| std::vector<uint64_t> values(32); |
| std::iota(values.begin(), values.end(), 0); |
| |
| BitmapValue bitmap_value5(values); |
| EXPECT_EQ(bitmap_value5.get_type_code(), BitmapTypeCode::SET); |
| |
| values.clear(); |
| values.resize(64); |
| std::iota(values.begin(), values.end(), 0); |
| BitmapValue bitmap_value6(values); |
| EXPECT_EQ(bitmap_value6.get_type_code(), BitmapTypeCode::BITMAP32); |
| |
| bitmap_value6.add(4294967297); |
| EXPECT_EQ(bitmap_value6.get_type_code(), BitmapTypeCode::BITMAP64); |
| |
| config::enable_set_in_bitmap_value = false; |
| } |
| |
| TEST(BitmapValueTest, add) { |
| config::enable_set_in_bitmap_value = true; |
| |
| std::vector<uint64_t> values(1); |
| std::iota(values.begin(), values.end(), 0); |
| BitmapValue bitmap_value(values); |
| |
| EXPECT_EQ(bitmap_value.get_type_code(), BitmapTypeCode::SINGLE32); |
| |
| bitmap_value.add(2); |
| EXPECT_EQ(bitmap_value.get_type_code(), BitmapTypeCode::SET); |
| |
| bitmap_value.add(3); |
| EXPECT_EQ(bitmap_value.get_type_code(), BitmapTypeCode::SET); |
| EXPECT_EQ(bitmap_value.cardinality(), 3); |
| |
| bitmap_value.remove(3); |
| EXPECT_EQ(bitmap_value.cardinality(), 2); |
| EXPECT_FALSE(bitmap_value.contains(3)); |
| |
| values.clear(); |
| values.resize(32); |
| std::iota(values.begin(), values.end(), 1); |
| bitmap_value.add_many(values.data(), values.size()); |
| EXPECT_EQ(bitmap_value.get_type_code(), BitmapTypeCode::BITMAP32); |
| |
| values.clear(); |
| values.resize(32); |
| std::iota(values.begin(), values.end(), 32); |
| bitmap_value.add_many(values.data(), values.size()); |
| EXPECT_EQ(bitmap_value.get_type_code(), BitmapTypeCode::BITMAP32); |
| |
| bitmap_value.reset(); |
| values.clear(); |
| values.resize(31); |
| std::iota(values.begin(), values.end(), 0); |
| |
| bitmap_value.add_many(values.data(), values.size()); |
| EXPECT_EQ(bitmap_value.get_type_code(), BitmapTypeCode::SET); |
| |
| values.clear(); |
| values.resize(32); |
| std::iota(values.begin(), values.end(), 32); |
| bitmap_value.add_many(values.data(), values.size()); |
| EXPECT_EQ(bitmap_value.get_type_code(), BitmapTypeCode::BITMAP32); |
| config::enable_set_in_bitmap_value = false; |
| } |
| |
| void check_bitmap_value_operator(const BitmapValue& left, const BitmapValue& right) { |
| auto left_cardinality = left.cardinality(); |
| auto right_cardinality = right.cardinality(); |
| auto and_cardinality = left.and_cardinality(right); |
| auto and_not_cardinality = left.andnot_cardinality(right); |
| |
| std::cout << "left_cardinality: " << left_cardinality |
| << ", right_cardinality: " << right_cardinality |
| << ", and_cardinality: " << and_cardinality |
| << ", and_not_cardinality: " << and_not_cardinality << std::endl; |
| |
| EXPECT_EQ(left_cardinality, and_cardinality + and_not_cardinality); |
| |
| EXPECT_LE(and_cardinality, left_cardinality); |
| EXPECT_LE(and_cardinality, right_cardinality); |
| EXPECT_EQ(and_not_cardinality, left_cardinality - and_cardinality); |
| |
| auto copy = left; |
| copy -= right; |
| EXPECT_EQ(copy.cardinality(), and_not_cardinality); |
| |
| copy = left; |
| copy |= right; |
| std::cout << "copy.cardinality(): " << copy.cardinality() << std::endl; |
| EXPECT_EQ(copy.cardinality(), left_cardinality + right_cardinality - and_cardinality); |
| |
| copy = left; |
| copy &= right; |
| EXPECT_EQ(copy.cardinality(), and_cardinality); |
| |
| copy = left; |
| copy ^= right; |
| EXPECT_EQ(copy.cardinality(), left_cardinality + right_cardinality - and_cardinality * 2); |
| } |
| |
| // '=' |
| TEST(BitmapValueTest, copy_operator) { |
| BitmapValue test_bitmap; |
| |
| std::vector<uint64_t> values1(31); |
| BitmapValue bitmap; |
| values1.resize(128); |
| std::iota(values1.begin(), values1.begin() + 16, 0); |
| std::iota(values1.begin() + 16, values1.begin() + 32, 4294967297); |
| std::iota(values1.begin() + 32, values1.begin() + 64, 8589934594); |
| std::iota(values1.begin() + 64, values1.end(), 42949672970); |
| bitmap.add_many(values1.data(), values1.size()); |
| |
| test_bitmap = bitmap; //should be bitmap |
| EXPECT_EQ(test_bitmap.cardinality(), bitmap.cardinality()); |
| EXPECT_EQ(test_bitmap.to_string(), bitmap.to_string()); |
| |
| BitmapValue single(1); |
| test_bitmap = single; //should be single |
| EXPECT_EQ(test_bitmap.cardinality(), 1); |
| EXPECT_EQ(test_bitmap.cardinality(), single.cardinality()); |
| EXPECT_EQ(test_bitmap.to_string(), single.to_string()); |
| |
| BitmapValue empty; |
| test_bitmap = empty; // should be empty |
| EXPECT_TRUE(test_bitmap.empty()); |
| |
| BitmapValue bitmap2(bitmap); |
| EXPECT_EQ(bitmap2.to_string(), bitmap.to_string()); |
| bitmap2 = bitmap; |
| EXPECT_EQ(bitmap2.to_string(), bitmap.to_string()); |
| } |
| |
| // '-=', '|=', '&=', '^=' |
| TEST(BitmapValueTest, operators) { |
| config::enable_set_in_bitmap_value = true; |
| BitmapValue left_empty; |
| BitmapValue right_emtpy; |
| |
| BitmapValue left_single(1); |
| BitmapValue right_single(2); |
| |
| BitmapValue left_set; |
| BitmapValue right_set; |
| |
| std::vector<uint64_t> values1(31); |
| std::vector<uint64_t> values2(31); |
| |
| std::iota(values1.begin(), values1.end(), 0); |
| std::iota(values2.begin(), values2.end(), 17); |
| |
| left_set.add_many(values1.data(), values1.size()); |
| right_set.add_many(values2.data(), values2.size()); |
| |
| BitmapValue left_bitmap; |
| BitmapValue right_bitmap; |
| |
| values1.resize(128); |
| values2.resize(128); |
| |
| std::iota(values1.begin(), values1.begin() + 16, 0); |
| std::iota(values2.begin(), values2.begin() + 16, 8); |
| |
| std::iota(values1.begin() + 16, values1.begin() + 32, 4294967297); |
| std::iota(values2.begin() + 16, values2.begin() + 32, 4294967305); |
| |
| std::iota(values1.begin() + 32, values1.begin() + 64, 8589934594); |
| std::iota(values2.begin() + 32, values2.begin() + 64, 8589934626); |
| |
| std::iota(values1.begin() + 64, values1.end(), 42949672970); |
| std::iota(values2.begin() + 64, values2.end(), 42949673002); |
| |
| left_bitmap.add_many(values1.data(), values1.size()); |
| right_bitmap.add_many(values2.data(), values2.size()); |
| |
| check_bitmap_value_operator(left_empty, right_emtpy); |
| check_bitmap_value_operator(left_empty, right_single); |
| check_bitmap_value_operator(left_empty, right_set); |
| check_bitmap_value_operator(left_empty, right_bitmap); |
| |
| check_bitmap_value_operator(left_single, right_emtpy); |
| check_bitmap_value_operator(left_single, right_single); |
| check_bitmap_value_operator(left_single, right_set); |
| check_bitmap_value_operator(left_single, right_bitmap); |
| |
| check_bitmap_value_operator(left_set, right_emtpy); |
| check_bitmap_value_operator(left_set, right_single); |
| check_bitmap_value_operator(left_set, right_set); |
| check_bitmap_value_operator(left_set, right_bitmap); |
| |
| check_bitmap_value_operator(left_bitmap, right_emtpy); |
| check_bitmap_value_operator(left_bitmap, right_single); |
| check_bitmap_value_operator(left_bitmap, right_set); |
| check_bitmap_value_operator(left_bitmap, right_bitmap); |
| |
| config::enable_set_in_bitmap_value = false; |
| } |
| |
| void check_bitmap_equal(const BitmapValue& left, const BitmapValue& right) { |
| EXPECT_EQ(left.cardinality(), right.cardinality()); |
| EXPECT_EQ(left.minimum(), right.minimum()); |
| EXPECT_EQ(left.maximum(), right.maximum()); |
| |
| for (auto v : left) { |
| EXPECT_TRUE(right.contains(v)); |
| } |
| |
| for (auto v : right) { |
| EXPECT_TRUE(left.contains(v)); |
| } |
| } |
| |
| TEST(BitmapValueTest, write_read) { |
| config::enable_set_in_bitmap_value = true; |
| BitmapValue bitmap_empty; |
| BitmapValue bitmap_single(1); |
| BitmapValue bitmap_set; |
| BitmapValue bitmap; |
| |
| std::vector<uint64_t> values1(31); |
| |
| std::iota(values1.begin(), values1.end(), 0); |
| |
| bitmap_set.add_many(values1.data(), values1.size()); |
| |
| values1.resize(128); |
| |
| std::iota(values1.begin(), values1.begin() + 16, 0); |
| std::iota(values1.begin() + 16, values1.begin() + 32, 4294967297); |
| std::iota(values1.begin() + 32, values1.begin() + 64, 8589934594); |
| std::iota(values1.begin() + 64, values1.end(), 42949672970); |
| |
| bitmap.add_many(values1.data(), values1.size()); |
| |
| auto size = bitmap_empty.getSizeInBytes(); |
| std::unique_ptr<char[]> buffer(new char[size]); |
| |
| bitmap_empty.write_to(buffer.get()); |
| BitmapValue deserialized(buffer.get()); |
| |
| check_bitmap_equal(deserialized, bitmap_empty); |
| |
| size = bitmap_single.getSizeInBytes(); |
| buffer.reset(new char[size]); |
| |
| bitmap_single.write_to(buffer.get()); |
| deserialized.reset(); |
| deserialized.deserialize(buffer.get()); |
| |
| check_bitmap_equal(deserialized, bitmap_single); |
| |
| size = bitmap_set.getSizeInBytes(); |
| buffer.reset(new char[size]); |
| |
| bitmap_set.write_to(buffer.get()); |
| deserialized.reset(); |
| deserialized.deserialize(buffer.get()); |
| |
| check_bitmap_equal(deserialized, bitmap_set); |
| |
| size = bitmap.getSizeInBytes(); |
| buffer.reset(new char[size]); |
| |
| bitmap.write_to(buffer.get()); |
| deserialized.reset(); |
| deserialized.deserialize(buffer.get()); |
| |
| check_bitmap_equal(deserialized, bitmap); |
| |
| config::enable_set_in_bitmap_value = false; |
| } |
| |
| TEST(BitmapValueTest, set_to_string) { |
| config::enable_set_in_bitmap_value = true; |
| BitmapValue bitmap; |
| bitmap.add(1); |
| bitmap.add(2); |
| bitmap.add(3); |
| |
| EXPECT_EQ(bitmap.get_type_code(), BitmapTypeCode::SET); |
| |
| EXPECT_EQ(bitmap.to_string(), "1,2,3"); |
| config::enable_set_in_bitmap_value = false; |
| } |
| |
| TEST(BitmapValueTest, min_max) { |
| config::enable_set_in_bitmap_value = true; |
| BitmapValue bitmap; |
| |
| bool empty {false}; |
| auto min = bitmap.min(&empty); |
| EXPECT_TRUE(empty); |
| auto max = bitmap.max(&empty); |
| EXPECT_TRUE(empty); |
| EXPECT_EQ(min, 0); |
| EXPECT_EQ(max, 0); |
| |
| bitmap.add(1); |
| min = bitmap.min(&empty); |
| EXPECT_FALSE(empty); |
| max = bitmap.max(&empty); |
| EXPECT_FALSE(empty); |
| EXPECT_EQ(min, 1); |
| EXPECT_EQ(max, 1); |
| |
| bitmap.add(2); |
| bitmap.add(3); |
| min = bitmap.min(&empty); |
| EXPECT_FALSE(empty); |
| max = bitmap.max(&empty); |
| EXPECT_FALSE(empty); |
| EXPECT_EQ(min, 1); |
| EXPECT_EQ(max, 3); |
| |
| std::vector<uint64_t> values(128); |
| |
| std::iota(values.begin(), values.begin() + 16, 0); |
| std::iota(values.begin() + 16, values.begin() + 32, 4294967297); |
| std::iota(values.begin() + 32, values.begin() + 64, 8589934594); |
| std::iota(values.begin() + 64, values.end(), 42949672970); |
| |
| bitmap.add_many(values.data(), values.size()); |
| min = bitmap.min(&empty); |
| EXPECT_FALSE(empty); |
| max = bitmap.max(&empty); |
| EXPECT_FALSE(empty); |
| EXPECT_EQ(min, 0); |
| EXPECT_EQ(max, bitmap.maximum()); |
| EXPECT_EQ(max, 42949672970 + 63); |
| |
| config::enable_set_in_bitmap_value = false; |
| } |
| |
| TEST(BitmapValueTest, sub_range_limit) { |
| config::enable_set_in_bitmap_value = true; |
| BitmapValue bitmap; |
| |
| BitmapValue out; |
| auto ret = bitmap.sub_range(0, 100, &out); |
| EXPECT_EQ(ret, 0); |
| |
| EXPECT_TRUE(out.empty()); |
| |
| ret = bitmap.sub_limit(0, 1, &out); |
| EXPECT_EQ(ret, 0); |
| EXPECT_TRUE(out.empty()); |
| |
| ret = bitmap.offset_limit(0, 1, &out); |
| EXPECT_EQ(ret, 0); |
| EXPECT_TRUE(out.empty()); |
| |
| BitmapValue bitmap_single(1); |
| ret = bitmap_single.sub_range(0, 100, &out); |
| EXPECT_EQ(ret, 1); |
| |
| ret = bitmap_single.sub_range(0, 1, &out); |
| EXPECT_EQ(ret, 0); |
| |
| ret = bitmap_single.sub_limit(0, 100, &out); |
| EXPECT_EQ(ret, 1); |
| |
| ret = bitmap_single.sub_limit(0, 1, &out); |
| EXPECT_EQ(ret, 1); |
| |
| ret = bitmap_single.offset_limit(0, 100, &out); |
| EXPECT_EQ(ret, 1); |
| |
| ret = bitmap_single.offset_limit(1, 1, &out); |
| EXPECT_EQ(ret, 0); |
| |
| bitmap.add(1); |
| bitmap.add(2); |
| ret = bitmap.sub_range(0, 100, &out); |
| EXPECT_EQ(ret, 2); |
| |
| ret = bitmap.sub_range(0, 2, &out); |
| EXPECT_EQ(ret, 1); |
| |
| ret = bitmap.sub_limit(0, 100, &out); |
| EXPECT_EQ(ret, 2); |
| |
| ret = bitmap.sub_limit(0, 2, &out); |
| EXPECT_EQ(ret, 2); |
| |
| ret = bitmap.offset_limit(0, 100, &out); |
| EXPECT_EQ(ret, 2); |
| |
| ret = bitmap.offset_limit(1, 2, &out); |
| EXPECT_EQ(ret, 1); |
| |
| std::vector<uint64_t> values(128); |
| |
| std::iota(values.begin(), values.begin() + 16, 0); |
| std::iota(values.begin() + 16, values.begin() + 32, 4294967297); |
| std::iota(values.begin() + 32, values.begin() + 64, 8589934594); |
| std::iota(values.begin() + 64, values.end(), 42949672970); |
| |
| bitmap.add_many(values.data(), values.size()); |
| ret = bitmap.sub_range(0, 42949672970 + 64, &out); |
| EXPECT_EQ(ret, bitmap.cardinality()); |
| |
| ret = bitmap.sub_range(0, 100, &out); |
| EXPECT_EQ(ret, 16); |
| |
| ret = bitmap.offset_limit(0, 10, &out); |
| EXPECT_EQ(ret, 10); |
| ret = bitmap.offset_limit(20, 10, &out); |
| EXPECT_EQ(ret, 10); |
| ret = bitmap.offset_limit(100, 10, &out); |
| EXPECT_EQ(ret, 10); |
| config::enable_set_in_bitmap_value = false; |
| } |
| |
| void bitmap_checker_for_all_type(const std::function<void(const BitmapValue&)>& checker) { |
| BitmapValue bitmap_empty; |
| BitmapValue bitmap_single(1); |
| BitmapValue bitmap_set; |
| BitmapValue bitmap; |
| |
| std::vector<uint64_t> values1(31); |
| |
| std::iota(values1.begin(), values1.end(), 0); |
| |
| bitmap_set.add_many(values1.data(), values1.size()); |
| |
| values1.resize(128); |
| |
| std::iota(values1.begin(), values1.begin() + 16, 0); |
| std::iota(values1.begin() + 16, values1.begin() + 32, 4294967297); |
| std::iota(values1.begin() + 32, values1.begin() + 64, 8589934594); |
| std::iota(values1.begin() + 64, values1.end(), 42949672970); |
| |
| bitmap.add_many(values1.data(), values1.size()); |
| |
| checker(bitmap_empty); |
| checker(bitmap_single); |
| checker(bitmap_set); |
| checker(bitmap); |
| } |
| |
| TEST(BitmapValueTest, to_array) { |
| config::enable_set_in_bitmap_value = true; |
| auto checker = [](const BitmapValue& bitmap) { |
| auto size = bitmap.cardinality(); |
| if (size == 0) { |
| EXPECT_TRUE(bitmap.empty()); |
| return; |
| } |
| |
| vectorized::PaddedPODArray<int64_t> data; |
| bitmap.to_array(data); |
| |
| for (size_t i = 0; i != size; ++i) { |
| EXPECT_TRUE(bitmap.contains(data[i])); |
| } |
| }; |
| |
| bitmap_checker_for_all_type(checker); |
| config::enable_set_in_bitmap_value = false; |
| } |
| |
| TEST(BitmapValueTest, BitmapValueIterator) { |
| config::enable_set_in_bitmap_value = true; |
| auto checker = [](const BitmapValue& bitmap) { |
| auto begin = bitmap.begin(); |
| const auto end = bitmap.end(); |
| |
| auto iter = begin; |
| while (iter != end) { |
| EXPECT_TRUE(bitmap.contains(*iter)); |
| ++iter; |
| } |
| EXPECT_EQ(end, iter); |
| |
| auto iter2 = begin; |
| while (iter2 != end) { |
| EXPECT_TRUE(bitmap.contains(*iter2)); |
| iter2++; |
| } |
| EXPECT_EQ(end, iter2); |
| }; |
| |
| bitmap_checker_for_all_type(checker); |
| config::enable_set_in_bitmap_value = false; |
| } |
| |
| TEST(BitmapValueTest, copy) { |
| BitmapValue empty; |
| BitmapValue single(1024); |
| BitmapValue bitmap({1024, 1025, 1026}); |
| |
| BitmapValue copied = bitmap; |
| EXPECT_TRUE(copied.contains(1024)); |
| EXPECT_TRUE(copied.contains(1025)); |
| EXPECT_TRUE(copied.contains(1026)); |
| copied &= single; |
| |
| // value of copied changed. |
| EXPECT_TRUE(copied.contains(1024)); |
| EXPECT_FALSE(copied.contains(1025)); |
| EXPECT_FALSE(copied.contains(1026)); |
| |
| // value of bitmap not changed. |
| EXPECT_TRUE(bitmap.contains(1024)); |
| EXPECT_TRUE(bitmap.contains(1025)); |
| EXPECT_TRUE(bitmap.contains(1026)); |
| } |
| |
| TEST(BitmapValueTest, bitmap_union) { |
| BitmapValue empty; |
| BitmapValue single(1024); |
| BitmapValue bitmap({1024, 1025, 1026}); |
| |
| EXPECT_EQ(0, empty.cardinality()); |
| EXPECT_EQ(1, single.cardinality()); |
| EXPECT_EQ(3, bitmap.cardinality()); |
| |
| BitmapValue empty2; |
| empty2 |= empty; |
| EXPECT_EQ(0, empty2.cardinality()); |
| empty2 |= single; |
| EXPECT_EQ(1, empty2.cardinality()); |
| BitmapValue empty3; |
| empty3 |= bitmap; |
| EXPECT_EQ(3, empty3.cardinality()); |
| |
| BitmapValue empty4; |
| empty4.fastunion({&empty}); |
| EXPECT_EQ(0, empty4.cardinality()); |
| empty4.fastunion({&single}); |
| EXPECT_EQ(1, empty4.cardinality()); |
| BitmapValue empty5; |
| empty5.fastunion({&bitmap}); |
| EXPECT_EQ(3, empty3.cardinality()); |
| BitmapValue empty6; |
| empty6.fastunion({&empty, &single, &bitmap}); |
| EXPECT_EQ(3, empty3.cardinality()); |
| |
| BitmapValue single2(1025); |
| single2 |= empty; |
| EXPECT_EQ(1, single2.cardinality()); |
| single2 |= single; |
| EXPECT_EQ(2, single2.cardinality()); |
| BitmapValue single3(1027); |
| single3 |= bitmap; |
| EXPECT_EQ(4, single3.cardinality()); |
| |
| BitmapValue single4(1025); |
| single4.fastunion({&empty}); |
| EXPECT_EQ(1, single4.cardinality()); |
| single4.fastunion({&single}); |
| EXPECT_EQ(2, single4.cardinality()); |
| BitmapValue single5(1027); |
| single5.fastunion({&bitmap}); |
| EXPECT_EQ(4, single5.cardinality()); |
| BitmapValue single6(1027); |
| single6.fastunion({&empty, &single, &bitmap}); |
| EXPECT_EQ(4, single6.cardinality()); |
| |
| BitmapValue bitmap2; |
| bitmap2.add(1024); |
| bitmap2.add(2048); |
| bitmap2.add(4096); |
| bitmap2 |= empty; |
| EXPECT_EQ(3, bitmap2.cardinality()); |
| bitmap2 |= single; |
| EXPECT_EQ(3, bitmap2.cardinality()); |
| bitmap2 |= bitmap; |
| EXPECT_EQ(5, bitmap2.cardinality()); |
| |
| BitmapValue bitmap3; |
| bitmap3.add(1024); |
| bitmap3.add(2048); |
| bitmap3.add(4096); |
| bitmap3.fastunion({&empty}); |
| EXPECT_EQ(3, bitmap3.cardinality()); |
| bitmap3.fastunion({&single}); |
| EXPECT_EQ(3, bitmap3.cardinality()); |
| bitmap3.fastunion({&bitmap}); |
| EXPECT_EQ(5, bitmap3.cardinality()); |
| |
| const auto old_config = config::enable_set_in_bitmap_value; |
| config::enable_set_in_bitmap_value = true; |
| BitmapValue bitmap4; // empty |
| |
| BitmapValue bitmap_set1; |
| BitmapValue bitmap_set2; |
| BitmapValue bitmap_set3; |
| |
| const int set_data1[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; |
| bitmap_set1.add_many(set_data1, 15); |
| |
| const int set_data2[] = {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30}; |
| bitmap_set2.add_many(set_data2, 15); |
| |
| const int set_data3[] = {31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45}; |
| bitmap_set3.add_many(set_data3, 15); |
| |
| bitmap4.fastunion({&bitmap_set1, &bitmap_set2, &bitmap_set3}); |
| |
| EXPECT_EQ(bitmap4.cardinality(), 45); |
| EXPECT_EQ(bitmap4.get_type_code(), BitmapTypeCode::BITMAP32); |
| config::enable_set_in_bitmap_value = old_config; |
| } |
| |
| TEST(BitmapValueTest, bitmap_intersect) { |
| BitmapValue empty; |
| BitmapValue single(1024); |
| BitmapValue bitmap({1024, 1025, 1026}); |
| |
| BitmapValue empty2; |
| empty2 &= empty; |
| EXPECT_EQ(0, empty2.cardinality()); |
| empty2 &= single; |
| EXPECT_EQ(0, empty2.cardinality()); |
| empty2 &= bitmap; |
| EXPECT_EQ(0, empty2.cardinality()); |
| |
| BitmapValue single2(1025); |
| single2 &= empty; |
| EXPECT_EQ(0, single2.cardinality()); |
| |
| BitmapValue single4(1025); |
| single4 &= single; |
| EXPECT_EQ(0, single4.cardinality()); |
| |
| BitmapValue single3(1024); |
| single3 &= single; |
| EXPECT_EQ(1, single3.cardinality()); |
| |
| single3 &= bitmap; |
| EXPECT_EQ(1, single3.cardinality()); |
| |
| BitmapValue single5(2048); |
| single5 &= bitmap; |
| EXPECT_EQ(0, single5.cardinality()); |
| |
| BitmapValue bitmap2; |
| bitmap2.add(1024); |
| bitmap2.add(2048); |
| bitmap2 &= empty; |
| EXPECT_EQ(0, bitmap2.cardinality()); |
| |
| BitmapValue bitmap3; |
| bitmap3.add(1024); |
| bitmap3.add(2048); |
| bitmap3 &= single; |
| EXPECT_EQ(1, bitmap3.cardinality()); |
| |
| BitmapValue bitmap4; |
| bitmap4.add(2049); |
| bitmap4.add(2048); |
| bitmap4 &= single; |
| EXPECT_EQ(0, bitmap4.cardinality()); |
| |
| BitmapValue bitmap5; |
| bitmap5.add(2049); |
| bitmap5.add(2048); |
| bitmap5 &= bitmap; |
| EXPECT_EQ(0, bitmap5.cardinality()); |
| |
| BitmapValue bitmap6; |
| bitmap6.add(1024); |
| bitmap6.add(1025); |
| bitmap6 &= bitmap; |
| EXPECT_EQ(2, bitmap6.cardinality()); |
| } |
| |
| std::string convert_bitmap_to_string(BitmapValue& bitmap) { |
| std::string buf; |
| buf.resize(bitmap.getSizeInBytes()); |
| bitmap.write_to((char*)buf.c_str()); |
| return buf; |
| } |
| |
| TEST(BitmapValueTest, bitmap_serde) { |
| { // EMPTY |
| BitmapValue empty; |
| std::string buffer = convert_bitmap_to_string(empty); |
| std::string expect_buffer(1, BitmapTypeCode::EMPTY); |
| EXPECT_EQ(expect_buffer, buffer); |
| |
| BitmapValue out(buffer.data()); |
| EXPECT_EQ(0, out.cardinality()); |
| } |
| { // SINGLE32 |
| uint32_t i = UINT32_MAX; |
| BitmapValue single32(i); |
| std::string buffer = convert_bitmap_to_string(single32); |
| std::string expect_buffer(1, BitmapTypeCode::SINGLE32); |
| put_fixed32_le(&expect_buffer, i); |
| EXPECT_EQ(expect_buffer, buffer); |
| |
| BitmapValue out(buffer.data()); |
| EXPECT_EQ(1, out.cardinality()); |
| EXPECT_TRUE(out.contains(i)); |
| } |
| { // BITMAP32 |
| BitmapValue bitmap32({0, UINT32_MAX}); |
| std::string buffer = convert_bitmap_to_string(bitmap32); |
| |
| BitmapValue out(buffer.data()); |
| EXPECT_EQ(2, out.cardinality()); |
| EXPECT_TRUE(out.contains(0)); |
| EXPECT_TRUE(out.contains(UINT32_MAX)); |
| } |
| { // SINGLE64 |
| uint64_t i = static_cast<uint64_t>(UINT32_MAX) + 1; |
| BitmapValue single64(i); |
| std::string buffer = convert_bitmap_to_string(single64); |
| std::string expect_buffer(1, BitmapTypeCode::SINGLE64); |
| put_fixed64_le(&expect_buffer, i); |
| EXPECT_EQ(expect_buffer, buffer); |
| |
| BitmapValue out(buffer.data()); |
| EXPECT_EQ(1, out.cardinality()); |
| EXPECT_TRUE(out.contains(i)); |
| } |
| { // BITMAP64 |
| BitmapValue bitmap64({0, static_cast<uint64_t>(UINT32_MAX) + 1}); |
| std::string buffer = convert_bitmap_to_string(bitmap64); |
| |
| BitmapValue out(buffer.data()); |
| EXPECT_EQ(2, out.cardinality()); |
| EXPECT_TRUE(out.contains(0)); |
| EXPECT_TRUE(out.contains(static_cast<uint64_t>(UINT32_MAX) + 1)); |
| } |
| } |
| |
| // Forked from CRoaring's UT of Roaring64Map |
| TEST(BitmapValueTest, Roaring64Map) { |
| using doris::detail::Roaring64Map; |
| // create a new empty bitmap |
| Roaring64Map r1; |
| uint64_t r1_sum = 0; |
| // then we can add values |
| for (uint64_t i = 100; i < 1000; i++) { |
| r1.add(i); |
| r1_sum += i; |
| } |
| for (uint64_t i = 14000000000000000100ull; i < 14000000000000001000ull; i++) { |
| r1.add(i); |
| r1_sum += i; |
| } |
| EXPECT_TRUE(r1.contains((uint64_t)14000000000000000500ull)); |
| EXPECT_EQ(1800, r1.cardinality()); |
| size_t size_before = r1.getSizeInBytes(1); |
| r1.runOptimize(); |
| size_t size_after = r1.getSizeInBytes(1); |
| EXPECT_LT(size_after, size_before); |
| |
| Roaring64Map r2; |
| r2.add((uint64_t)1); |
| r2.add((uint64_t)2); |
| r2.add((uint64_t)234294967296); |
| r2.add((uint64_t)195839473298); |
| r2.add((uint64_t)14000000000000000100ull); |
| EXPECT_EQ(1ull, r2.minimum()); |
| EXPECT_EQ(14000000000000000100ull, r2.maximum()); |
| |
| // we can also create a bitmap from a pointer to 32-bit integers |
| const uint32_t values[] = {2, 3, 4}; |
| Roaring64Map r3(3, values); |
| EXPECT_EQ(3, r3.cardinality()); |
| |
| // we can copy and compare bitmaps |
| Roaring64Map z(r3); |
| EXPECT_TRUE(r3 == z); |
| |
| // we can compute union two-by-two |
| Roaring64Map r1_2_3 = r1 | r2; |
| r1_2_3 |= r3; |
| |
| // we can compute a big union |
| const Roaring64Map* allmybitmaps[] = {&r1, &r2, &r3}; |
| Roaring64Map bigunion = Roaring64Map::fastunion(3, allmybitmaps); |
| EXPECT_TRUE(r1_2_3 == bigunion); |
| EXPECT_EQ(1806, r1_2_3.cardinality()); |
| |
| // we can compute intersection two-by-two |
| Roaring64Map i1_2 = r1 & r2; |
| EXPECT_EQ(1, i1_2.cardinality()); |
| |
| // we can write a bitmap to a pointer and recover it later |
| uint32_t expectedsize = r1.getSizeInBytes(1); |
| char* serializedbytes = new char[expectedsize]; |
| r1.write(serializedbytes, 1); |
| Roaring64Map t = Roaring64Map::read(serializedbytes); |
| EXPECT_TRUE(r1 == t); |
| delete[] serializedbytes; |
| |
| // we can iterate over all values using custom functions |
| uint64_t sum = 0; |
| auto func = [](uint64_t value, void* param) { |
| *(uint64_t*)param += value; |
| return true; // we always process all values |
| }; |
| r1.iterate(func, &sum); |
| EXPECT_EQ(r1_sum, sum); |
| |
| // we can also iterate the C++ way |
| sum = 0; |
| for (Roaring64Map::const_iterator i = t.begin(); i != t.end(); i++) { |
| sum += *i; |
| } |
| EXPECT_EQ(r1_sum, sum); |
| } |
| |
| TEST(BitmapValueTest, bitmap_to_string) { |
| BitmapValue empty; |
| EXPECT_STREQ("", empty.to_string().c_str()); |
| empty.add(1); |
| EXPECT_STREQ("1", empty.to_string().c_str()); |
| empty.add(2); |
| EXPECT_STREQ("1,2", empty.to_string().c_str()); |
| } |
| |
| TEST(BitmapValueTest, sub_limit) { |
| BitmapValue bitmap({1, 2, 3, 10, 11, 5, 6, 7, 8, 9}); |
| BitmapValue ret_bitmap1; |
| EXPECT_EQ(5, bitmap.sub_limit(0, 5, &ret_bitmap1)); |
| EXPECT_STREQ("1,2,3,5,6", ret_bitmap1.to_string().c_str()); |
| |
| BitmapValue ret_bitmap2; |
| EXPECT_EQ(6, bitmap.sub_limit(6, 10, &ret_bitmap2)); |
| EXPECT_STREQ("6,7,8,9,10,11", ret_bitmap2.to_string().c_str()); |
| |
| BitmapValue ret_bitmap3; |
| EXPECT_EQ(3, bitmap.sub_limit(5, 3, &ret_bitmap3)); |
| EXPECT_STREQ("5,6,7", ret_bitmap3.to_string().c_str()); |
| |
| BitmapValue ret_bitmap4; |
| EXPECT_EQ(5, bitmap.sub_limit(2, 5, &ret_bitmap4)); |
| EXPECT_STREQ("2,3,5,6,7", ret_bitmap4.to_string().c_str()); |
| } |
| |
| TEST(BitmapValueTest, bitmap_single_convert) { |
| BitmapValue bitmap; |
| EXPECT_STREQ("", bitmap.to_string().c_str()); |
| bitmap.add(1); |
| EXPECT_STREQ("1", bitmap.to_string().c_str()); |
| bitmap.add(1); |
| EXPECT_STREQ("1", bitmap.to_string().c_str()); |
| EXPECT_EQ(BitmapValue::SINGLE, bitmap._type); |
| |
| BitmapValue bitmap_u; |
| bitmap_u.add(1); |
| bitmap |= bitmap_u; |
| EXPECT_EQ(BitmapValue::SINGLE, bitmap._type); |
| |
| bitmap_u.add(2); |
| EXPECT_EQ(BitmapValue::BITMAP, bitmap_u._type); |
| |
| bitmap |= bitmap_u; |
| EXPECT_EQ(BitmapValue::BITMAP, bitmap._type); |
| } |
| |
| TEST(BitmapValueTest, bitmap_value_iterator_test) { |
| BitmapValue empty; |
| for (auto iter = empty.begin(); iter != empty.end(); ++iter) { |
| // should not goes here |
| EXPECT_TRUE(false); |
| } |
| |
| BitmapValue single(1024); |
| auto single_iter = single.begin(); |
| EXPECT_EQ(1024, *single_iter); |
| EXPECT_TRUE(single_iter == BitmapValue {1024}.begin()); |
| EXPECT_TRUE(single_iter != single.end()); |
| |
| ++single_iter; |
| EXPECT_TRUE(single_iter == single.end()); |
| |
| int i = 0; |
| BitmapValue bitmap({0, 1025, 1026, UINT32_MAX, UINT64_MAX}); |
| for (auto iter = bitmap.begin(); iter != bitmap.end(); ++iter, ++i) { |
| switch (i) { |
| case 0: |
| EXPECT_EQ(0, *iter); |
| break; |
| case 1: |
| EXPECT_EQ(1025, *iter); |
| break; |
| case 2: |
| EXPECT_EQ(1026, *iter); |
| break; |
| case 3: |
| EXPECT_EQ(UINT32_MAX, *iter); |
| break; |
| case 4: |
| EXPECT_EQ(UINT64_MAX, *iter); |
| break; |
| default: |
| EXPECT_TRUE(false); |
| } |
| } |
| } |
| } // namespace doris |