/* vim:set ts=2 sw=2 sts=2 et: */
/**
* \author Marcus Holland-Moritz (github@mhxnet.de)
* \copyright Copyright (c) Marcus Holland-Moritz
*
* This file is part of dwarfs.
*
* dwarfs is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dwarfs is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with dwarfs. If not, see .
*/
#include
#include
#include
#include
namespace {
using dwarfs::reader::internal::lru_cache;
using unique_str_ptr = std::unique_ptr;
} // namespace
// Test for integral keys and regular types (e.g., std::string)
TEST(lru_cache_test, insert_and_retrieve_with_integral_key) {
lru_cache cache(3);
cache.set(1, "one");
cache.set(2, "two");
cache.set(3, "three");
// Retrieve and verify
ASSERT_EQ(cache.find(1)->second, "one");
ASSERT_EQ(cache.find(2)->second, "two");
ASSERT_EQ(cache.find(3)->second, "three");
}
TEST(lru_cache_test, insert_eviction_with_integral_key) {
lru_cache cache(3);
cache.set(1, "one");
cache.set(2, "two");
cache.set(3, "three");
// Evict least recently used (key 1)
cache.set(4, "four");
// Verify eviction
ASSERT_EQ(cache.find(1), cache.end());
ASSERT_EQ(cache.find(2)->second, "two");
ASSERT_EQ(cache.find(3)->second, "three");
ASSERT_EQ(cache.find(4)->second, "four");
}
TEST(lru_cache_test, find_with_promotion) {
lru_cache cache(3);
cache.set(1, "one");
cache.set(2, "two");
cache.set(3, "three");
// Access item to promote
cache.find(2);
// Add a new item, evicting the least recently used (key 1)
cache.set(4, "four");
// Verify promotion and eviction
ASSERT_EQ(cache.find(2)->second, "two");
ASSERT_EQ(cache.find(1), cache.end());
ASSERT_EQ(cache.find(3)->second, "three");
ASSERT_EQ(cache.find(4)->second, "four");
}
TEST(lru_cache_test, prune_hook) {
lru_cache cache(3);
std::vector> evicted_items;
// Set a prune hook to capture evicted keys
cache.set_prune_hook([&evicted_items](int key, std::string&& value) {
evicted_items.emplace_back(key, std::move(value));
});
cache.set(1, "one");
cache.set(2, "two");
cache.set(3, "three");
cache.set(4, "four");
// Verify that the least recently used key is evicted
ASSERT_EQ(evicted_items.size(), 1);
EXPECT_EQ(evicted_items[0].first, 1);
EXPECT_EQ(evicted_items[0].second, "one");
}
TEST(lru_cache_test, unique_ptr_key_type) {
lru_cache cache(3);
cache.set(1, std::make_unique("one"));
cache.set(2, std::make_unique("two"));
cache.set(3, std::make_unique("three"));
// Retrieve and verify unique_ptr values
auto val1 = std::move(cache.find(1)->second);
auto val2 = std::move(cache.find(2)->second);
auto val3 = std::move(cache.find(3)->second);
ASSERT_EQ(*val1, "one");
ASSERT_EQ(*val2, "two");
ASSERT_EQ(*val3, "three");
// Add a new item, evicting the least recently used (key 1)
cache.set(4, std::make_unique("four"));
// Verify eviction of key 1
ASSERT_EQ(cache.find(1), cache.end());
}
TEST(lru_cache_test, unique_ptr_eviction) {
lru_cache cache(3);
std::vector> evicted_items;
// Set a prune hook to capture evicted values
cache.set_prune_hook([&evicted_items](int key, unique_str_ptr&& value) {
evicted_items.emplace_back(key, std::move(value));
});
cache.set(1, std::make_unique("one"));
cache.set(2, std::make_unique("two"));
cache.set(3, std::make_unique("three"));
cache.set(4, std::make_unique("four"));
// Verify that the least recently used key (key 1) was evicted
ASSERT_EQ(evicted_items.size(), 1);
EXPECT_EQ(evicted_items[0].first, 1);
EXPECT_EQ(*evicted_items[0].second, "one");
}
TEST(lru_cache_test, clear_cache) {
lru_cache cache(3);
cache.set(1, "one");
cache.set(2, "two");
cache.set(3, "three");
// Clear the cache
cache.clear();
// Verify that the cache is empty
ASSERT_TRUE(cache.empty());
ASSERT_EQ(cache.size(), 0);
}