blob: 69496c49e07886f602dd5d424f3c2a53435cf513 [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 "lib/MapCache.h"
using namespace pulsar;
struct MoveOnlyInt {
int x = 0;
MoveOnlyInt() = default;
MoveOnlyInt(int xx) : x(xx) {}
MoveOnlyInt(const MoveOnlyInt&) = delete;
MoveOnlyInt(MoveOnlyInt&& rhs) noexcept : x(rhs.x) {}
bool operator=(const MoveOnlyInt& rhs) const { return x == rhs.x; }
};
TEST(MapCacheTest, testPutIfAbsent) {
MapCache<int, MoveOnlyInt> cache;
ASSERT_NE(cache.putIfAbsent(1, {100}), cache.end());
ASSERT_EQ(cache.putIfAbsent(1, {200}), cache.end());
auto it = cache.find(1);
ASSERT_NE(it, cache.end());
ASSERT_EQ(it->second.x, 100);
cache.remove(1);
ASSERT_EQ(cache.find(1), cache.end());
}
TEST(MapCacheTest, testRemoveOldestValues) {
MapCache<int, MoveOnlyInt> cache;
cache.putIfAbsent(1, {200});
cache.putIfAbsent(2, {210});
cache.putIfAbsent(3, {220});
ASSERT_EQ(cache.getKeys(), (std::vector<int>{1, 2, 3}));
std::vector<int> removedValues;
cache.removeOldestValues(2, [&removedValues](const int& key, const MoveOnlyInt& value) {
removedValues.emplace_back(value.x);
});
ASSERT_EQ(removedValues, (std::vector<int>{200, 210}));
ASSERT_EQ(cache.getKeys(), (std::vector<int>{3}));
ASSERT_EQ(cache.size(), 1);
auto it = cache.find(3);
ASSERT_NE(it, cache.end());
ASSERT_EQ(it->second.x, 220);
}
TEST(MapCacheTest, testRemoveAllValues) {
MapCache<int, MoveOnlyInt> cache;
cache.putIfAbsent(1, {300});
cache.putIfAbsent(2, {310});
cache.putIfAbsent(3, {320});
// removeOldestValues works well even if the argument is greater than the size of keys
cache.removeOldestValues(10000, nullptr);
ASSERT_TRUE(cache.getKeys().empty());
ASSERT_EQ(cache.size(), 0);
}
TEST(MapCacheTest, testRemoveOldestValuesIf) {
MapCache<int, MoveOnlyInt> cache;
cache.putIfAbsent(1, {100});
cache.putIfAbsent(2, {200});
cache.putIfAbsent(3, {300});
int expireTime = 100;
auto checkCondition = [&expireTime](const int& key, const MoveOnlyInt& value) -> bool {
return expireTime > value.x;
};
cache.removeOldestValuesIf(nullptr);
ASSERT_EQ(cache.size(), 3);
cache.removeOldestValuesIf(checkCondition);
ASSERT_EQ(cache.size(), 3);
expireTime = 200;
cache.removeOldestValuesIf(checkCondition);
auto keys = cache.getKeys();
ASSERT_EQ(cache.size(), 2);
ASSERT_EQ(cache.find(2)->second.x, 200);
ASSERT_EQ(cache.find(3)->second.x, 300);
expireTime = 400;
cache.removeOldestValuesIf(checkCondition);
ASSERT_EQ(cache.size(), 0);
}