#include #include #include #include using namespace psemek::util; test_case(util_lru__cache_empty) { lru_cache c(64); expect_equal(c.size(), 0); expect(c.empty()); } test_case(util_lru__cache_insert) { lru_cache 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 c(64); expect_equal(c.size(), 0); expect(c.empty()); std::unordered_map 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 c(16); expect_equal(c.size(), 0); expect(c.empty()); expect_equal(c.max_size(), 16); std::unordered_map 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 c(64); expect_equal(c.size(), 0); expect(c.empty()); std::unordered_map 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> c(16, removable); expect_equal(c.size(), 0); expect(c.empty()); std::unordered_map 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)); } }