blob: b0777a9d944bc866c18052444a966ca53c0f8d04 [file]
/*
* 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 "common/cache/lru_cache.h"
#include <gtest/gtest.h>
#include <memory>
#include <string>
namespace common {
TEST(LruCacheTest, StrictCapacityPromotesAndEvicts) {
Cache<int, std::string> cache(2, 0);
cache.insert(1, "one");
cache.insert(2, "two");
const std::string* one = cache.getPtr(1);
ASSERT_NE(one, nullptr);
EXPECT_EQ(*one, "one");
cache.insert(3, "three");
EXPECT_TRUE(cache.contains(1));
EXPECT_FALSE(cache.contains(2));
EXPECT_TRUE(cache.contains(3));
EXPECT_EQ(cache.size(), 2u);
}
TEST(LruCacheTest, UpdateReplacesValueAndPromotes) {
Cache<int, std::string> cache(2, 0);
cache.insert(1, "one");
cache.insert(2, "two");
cache.insert(1, "updated");
cache.insert(3, "three");
EXPECT_EQ(cache.getRef(1), "updated");
EXPECT_FALSE(cache.contains(2));
}
TEST(LruCacheTest, ElasticityPrunesAfterHardLimitIsExceeded) {
Cache<int, int> cache(2, 2);
for (int i = 1; i <= 4; ++i) {
cache.insert(i, i);
}
EXPECT_EQ(cache.size(), 4u);
EXPECT_EQ(cache.getMaxAllowedSize(), 4u);
cache.insert(5, 5);
EXPECT_EQ(cache.size(), 2u);
EXPECT_TRUE(cache.contains(5));
EXPECT_TRUE(cache.contains(4));
EXPECT_FALSE(cache.contains(3));
}
TEST(LruCacheTest, CopyAndReferenceLookupsAreExplicit) {
Cache<int, std::string> cache(2, 0);
cache.insert(1, "one");
std::string copied;
EXPECT_TRUE(cache.tryGetCopy(1, copied));
EXPECT_EQ(copied, "one");
const std::string* ref = nullptr;
EXPECT_TRUE(cache.tryGetRef(1, ref));
ASSERT_NE(ref, nullptr);
EXPECT_EQ(*ref, "one");
EXPECT_EQ(cache.getCopy(1), "one");
EXPECT_THROW(cache.getRef(99), std::out_of_range);
}
TEST(LruCacheTest, NonCopyingLookupSupportsMoveOnlyValues) {
Cache<int, std::unique_ptr<int>> cache(1, 0);
cache.insert(1, std::unique_ptr<int>(new int(7)));
const std::unique_ptr<int>* value = nullptr;
ASSERT_TRUE(cache.tryGetRef(1, value));
ASSERT_NE(value, nullptr);
ASSERT_NE(value->get(), nullptr);
EXPECT_EQ(**value, 7);
cache.insert(1, std::unique_ptr<int>(new int(9)));
value = cache.getPtr(1);
ASSERT_NE(value, nullptr);
EXPECT_EQ(**value, 9);
}
TEST(LruCacheTest, RemoveClearAndUnboundedMode) {
Cache<int, int> bounded(2, 0);
bounded.insert(1, 1);
EXPECT_TRUE(bounded.remove(1));
EXPECT_FALSE(bounded.remove(1));
bounded.insert(2, 2);
bounded.clear();
EXPECT_TRUE(bounded.empty());
Cache<int, int> unbounded(0, 100);
for (int i = 0; i < 200; ++i) {
unbounded.insert(i, i);
}
EXPECT_EQ(unbounded.size(), 200u);
EXPECT_EQ(unbounded.getMaxAllowedSize(), 0u);
}
} // namespace common