158 lines
3.2 KiB
C++
158 lines
3.2 KiB
C++
#include <psemek/test/test.hpp>
|
|
|
|
#include <psemek/util/lru_cache.hpp>
|
|
#include <psemek/util/function.hpp>
|
|
|
|
#include <unordered_map>
|
|
|
|
using namespace psemek::util;
|
|
|
|
test_case(util_lru__cache_empty)
|
|
{
|
|
lru_cache<int, int> c(64);
|
|
expect_equal(c.size(), 0);
|
|
expect(c.empty());
|
|
}
|
|
|
|
test_case(util_lru__cache_insert)
|
|
{
|
|
lru_cache<int, int> c(64);
|
|
expect_equal(c.size(), 0);
|
|
expect(c.empty());
|
|
|
|
for (int key = 0; key < 32; ++key)
|
|
{
|
|
int const value = key * key;
|
|
c.insert(key, value);
|
|
expect_lequal(c.size(), key + 1);
|
|
expect(c.contains(key));
|
|
expect(c.find(key) != c.end());
|
|
expect_equal(c.at(key), value);
|
|
expect_equal(c.find(key)->first, key);
|
|
expect_equal(c.find(key)->second, value);
|
|
}
|
|
}
|
|
|
|
test_case(util_lru__cache_iterate)
|
|
{
|
|
lru_cache<int, int> c(64);
|
|
expect_equal(c.size(), 0);
|
|
expect(c.empty());
|
|
|
|
std::unordered_map<int, int> inserted;
|
|
|
|
for (int key = 0; key < 32; ++key)
|
|
{
|
|
int const value = key * key;
|
|
c.insert(key, value);
|
|
inserted[key] = value;
|
|
}
|
|
|
|
for (auto const & p : c)
|
|
{
|
|
expect(inserted.contains(p.first));
|
|
expect_equal(inserted.at(p.first), p.second);
|
|
}
|
|
|
|
for (auto const & p : inserted)
|
|
{
|
|
expect(c.contains(p.first));
|
|
expect_equal(c.at(p.first), p.second);
|
|
}
|
|
}
|
|
|
|
test_case(util_lru__cache_shrink)
|
|
{
|
|
lru_cache<int, int> c(16);
|
|
expect_equal(c.size(), 0);
|
|
expect(c.empty());
|
|
expect_equal(c.max_size(), 16);
|
|
|
|
std::unordered_map<int, int> inserted;
|
|
|
|
for (int key = 0; key < 32; ++key)
|
|
{
|
|
int const value = key * key;
|
|
c.insert(key, value);
|
|
inserted[key] = value;
|
|
expect_lequal(c.size(), key + 1);
|
|
expect(c.contains(key));
|
|
expect(c.find(key) != c.end());
|
|
expect_equal(c.at(key), value);
|
|
expect_equal(c.find(key)->first, key);
|
|
expect_equal(c.find(key)->second, value);
|
|
|
|
expect_lequal(c.size(), c.max_size());
|
|
}
|
|
|
|
for (int key = 0; key < 16; ++key)
|
|
expect(!c.contains(key));
|
|
|
|
for (int key = 16; key < 32; ++key)
|
|
{
|
|
expect(c.contains(key));
|
|
expect_equal(c.at(key), inserted.at(key));
|
|
}
|
|
|
|
for (auto const & p : c)
|
|
{
|
|
expect(inserted.contains(p.first));
|
|
expect_equal(inserted.at(p.first), p.second);
|
|
}
|
|
}
|
|
|
|
test_case(util_lru__cache_touch)
|
|
{
|
|
lru_cache<int, int> c(64);
|
|
expect_equal(c.size(), 0);
|
|
expect(c.empty());
|
|
|
|
std::unordered_map<int, int> inserted;
|
|
|
|
for (int key = 0; key < 32; ++key)
|
|
{
|
|
int const value = key * key;
|
|
c.insert(key, value);
|
|
inserted[key] = value;
|
|
expect(c.find(key) == c.begin());
|
|
}
|
|
|
|
for (int key = 0; key < 32; ++key)
|
|
{
|
|
c.touch(key);
|
|
expect(c.find(key) == c.begin());
|
|
}
|
|
}
|
|
|
|
test_case(util_lru__cache_removable)
|
|
{
|
|
auto removable = [](int key, int){ return key % 2 == 1; };
|
|
|
|
lru_cache<int, int, function<bool(int, int)>> c(16, removable);
|
|
expect_equal(c.size(), 0);
|
|
expect(c.empty());
|
|
|
|
std::unordered_map<int, int> inserted;
|
|
|
|
for (int key = 0; key < 32; ++key)
|
|
{
|
|
int const value = key * key;
|
|
bool const is_removable = removable(key, value);
|
|
bool const should_contain = c.size() < c.max_size() || !is_removable;
|
|
|
|
c.insert(key, value);
|
|
inserted[key] = value;
|
|
if (should_contain)
|
|
expect(c.contains(key));
|
|
|
|
if (!is_removable)
|
|
expect(c.find(key) == c.begin());
|
|
}
|
|
|
|
expect_equal(c.size(), c.max_size());
|
|
for (auto const & p : c)
|
|
{
|
|
expect_equal(inserted.at(p.first), p.second);
|
|
expect(!removable(p.first, p.second));
|
|
}
|
|
}
|