blob: be23f6d0b3c97fb1302ff475aa8d82880d1fd51e [file] [log] [blame]
/**
* 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 <gtest/gtest.h>
#include <map>
#include <vector>
#include "lib/BatchMessageAcker.h"
#include "lib/BitSet.h"
using namespace pulsar;
static std::vector<uint64_t> toLongVector(const BitSet& bitSet) {
std::vector<uint64_t> v;
for (uint64_t x : bitSet) {
v.emplace_back(x);
}
return v;
}
TEST(BitSetTest, testFill) {
// An int64_t has 64 bits, so we test 64*N + {-1, 0, 1}
std::map<int, std::vector<uint64_t>> expectedResults;
expectedResults[7] = {0x7f};
expectedResults[63] = {0x7fffffffffffffff};
expectedResults[64] = {0xffffffffffffffff};
expectedResults[65] = {0xffffffffffffffff, 1};
expectedResults[127] = {0xffffffffffffffff, 0x7fffffffffffffff};
expectedResults[128] = {0xffffffffffffffff, 0xffffffffffffffff};
expectedResults[129] = {0xffffffffffffffff, 0xffffffffffffffff, 1};
std::map<int, std::vector<uint64_t>> actualResults;
for (const auto& kv : expectedResults) {
BitSet bitSet(kv.first);
ASSERT_TRUE(toLongVector(bitSet).empty());
bitSet.set(0, kv.first);
actualResults[kv.first] = toLongVector(bitSet);
}
ASSERT_EQ(actualResults, expectedResults);
}
TEST(BitSetTest, testSet) {
BitSet bitSet(64 * 5 + 1); // 6 words
ASSERT_TRUE(toLongVector(bitSet).empty());
// range contains one word
bitSet.set(3, 29);
ASSERT_EQ(toLongVector(bitSet), std::vector<uint64_t>{0x1ffffff8});
for (int i = 0; i < 64 * 5 + 1; i++) {
if (i >= 3 && i < 29) {
ASSERT_TRUE(bitSet.get(i));
} else {
ASSERT_FALSE(bitSet.get(i));
}
}
// range contains multiple words
bitSet.set(64 * 2 + 11, 64 * 4 + 19);
ASSERT_EQ(toLongVector(bitSet),
(std::vector<uint64_t>{0x1ffffff8, 0, 0xfffffffffffff800, 0xffffffffffffffff, 0x7ffff}));
}
TEST(BitSetTest, testRangeClear) {
BitSet bitSet(64 * 5 + 1); // 6 words
bitSet.set(0, 64 * 5 + 1);
ASSERT_EQ(toLongVector(bitSet),
(std::vector<uint64_t>{0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
0xffffffffffffffff, 0xffffffffffffffff, 1}));
// range contains one word
bitSet.clear(64 * 5, 64 * 5 + 1);
ASSERT_EQ(toLongVector(bitSet),
(std::vector<uint64_t>{0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
0xffffffffffffffff, 0xffffffffffffffff}));
// range contains multiple words
bitSet.clear(64 * 2 + 13, 64 * 5);
ASSERT_EQ(toLongVector(bitSet), (std::vector<uint64_t>{0xffffffffffffffff, 0xffffffffffffffff, 0x1fff}));
}
TEST(BitSetTest, testSingleClear) {
BitSet bitSet(64 * 2 + 1); // 3 words
bitSet.set(0, 64 * 2 + 1);
ASSERT_EQ(toLongVector(bitSet), (std::vector<uint64_t>{0xffffffffffffffff, 0xffffffffffffffff, 1}));
// words in use shrinked
bitSet.clear(64 * 2);
ASSERT_EQ(toLongVector(bitSet), (std::vector<uint64_t>{0xffffffffffffffff, 0xffffffffffffffff}));
// words in use doesn't change
bitSet.clear(13);
ASSERT_EQ(toLongVector(bitSet), (std::vector<uint64_t>{0xffffffffffffdfff, 0xffffffffffffffff}));
}