diff options
Diffstat (limited to 'gd/common/lru_cache_test.cc')
-rw-r--r-- | gd/common/lru_cache_test.cc | 461 |
1 files changed, 0 insertions, 461 deletions
diff --git a/gd/common/lru_cache_test.cc b/gd/common/lru_cache_test.cc deleted file mode 100644 index 62b03dd2e..000000000 --- a/gd/common/lru_cache_test.cc +++ /dev/null @@ -1,461 +0,0 @@ -/* - * Copyright 2020 The Android Open Source Project - * - * Licensed 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 <chrono> -#include <limits> - -#include <gmock/gmock.h> -#include <gtest/gtest.h> - -#include "common/lru_cache.h" - -namespace testing { - -using bluetooth::common::LruCache; - -TEST(LruCacheTest, empty_test) { - LruCache<int, int> cache(3); // capacity = 3; - EXPECT_EQ(cache.size(), 0); - EXPECT_EQ(cache.find(42), cache.end()); - cache.clear(); // should not crash - EXPECT_EQ(cache.find(42), cache.end()); - EXPECT_FALSE(cache.contains(42)); - EXPECT_FALSE(cache.extract(42)); -} - -TEST(LruCacheTest, comparison_test) { - LruCache<int, int> cache_1(2); - cache_1.insert_or_assign(1, 10); - cache_1.insert_or_assign(2, 20); - LruCache<int, int> cache_2(2); - cache_2.insert_or_assign(1, 10); - cache_2.insert_or_assign(2, 20); - EXPECT_EQ(cache_1, cache_2); - // Cache with different order should not be equal - cache_2.find(1); - EXPECT_NE(cache_1, cache_2); - cache_1.find(1); - EXPECT_EQ(cache_1, cache_2); - // Cache with different value should be different - cache_2.insert_or_assign(1, 11); - EXPECT_NE(cache_1, cache_2); - // Cache with different capacity should not be equal - LruCache<int, int> cache_3(3); - cache_3.insert_or_assign(1, 10); - cache_3.insert_or_assign(2, 20); - EXPECT_NE(cache_1, cache_3); - // Empty cache should not be equal to non-empty ones - LruCache<int, int> cache_4(2); - EXPECT_NE(cache_1, cache_4); - // Empty caches should be equal - LruCache<int, int> cache_5(2); - EXPECT_EQ(cache_4, cache_5); - // Empty caches with different capacity should not be equal - LruCache<int, int> cache_6(3); - EXPECT_NE(cache_4, cache_6); -} - -TEST(LruCacheTest, try_emplace_test) { - LruCache<int, int> cache(2); - cache.insert_or_assign(1, 10); - cache.insert_or_assign(2, 20); - auto result = cache.try_emplace(42, 420); - // 1, 10 evicted - EXPECT_EQ(std::get<2>(result), std::make_pair(1, 10)); - auto iter = cache.find(42); - EXPECT_EQ(iter->second, 420); - EXPECT_EQ(iter, std::get<0>(result)); - ASSERT_THAT(cache, ElementsAre(Pair(42, 420), Pair(2, 20))); -} - -TEST(LruCacheTest, copy_test) { - LruCache<int, std::shared_ptr<int>> cache(2); - cache.insert_or_assign(1, std::make_shared<int>(100)); - auto iter = cache.find(1); - EXPECT_EQ(*iter->second, 100); - LruCache<int, std::shared_ptr<int>> new_cache = cache; - iter = new_cache.find(1); - EXPECT_EQ(*iter->second, 100); - *iter->second = 300; - iter = new_cache.find(1); - EXPECT_EQ(*iter->second, 300); - // Since copy is used, shared_ptr should increase count - EXPECT_EQ(iter->second.use_count(), 2); -} - -TEST(LruCacheTest, move_test) { - LruCache<int, std::shared_ptr<int>> cache(2); - cache.insert_or_assign(1, std::make_shared<int>(100)); - auto iter = cache.find(1); - EXPECT_EQ(*iter->second, 100); - LruCache<int, std::shared_ptr<int>> new_cache = std::move(cache); - iter = new_cache.find(1); - EXPECT_EQ(*iter->second, 100); - *iter->second = 300; - iter = new_cache.find(1); - EXPECT_EQ(*iter->second, 300); - // Since move is used, shared_ptr should not increase count - EXPECT_EQ(iter->second.use_count(), 1); -} - -TEST(LruCacheTest, move_insert_unique_ptr_test) { - LruCache<int, std::unique_ptr<int>> cache(2); - cache.insert_or_assign(1, std::make_unique<int>(100)); - auto iter = cache.find(1); - EXPECT_EQ(*iter->second, 100); - cache.insert_or_assign(1, std::make_unique<int>(400)); - iter = cache.find(1); - EXPECT_EQ(*iter->second, 400); -} - -TEST(LruCacheTest, move_insert_cache_test) { - LruCache<int, LruCache<int, int>> cache(2); - LruCache<int, int> m1(2); - m1.insert_or_assign(1, 100); - cache.insert_or_assign(1, std::move(m1)); - auto iter = cache.find(1); - EXPECT_THAT(iter->second, ElementsAre(Pair(1, 100))); - LruCache<int, int> m2(2); - m2.insert_or_assign(2, 200); - cache.insert_or_assign(1, std::move(m2)); - iter = cache.find(1); - EXPECT_THAT(iter->second, ElementsAre(Pair(2, 200))); -} - -TEST(LruCacheTest, erase_one_item_test) { - LruCache<int, int> cache(3); - cache.insert_or_assign(1, 10); - cache.insert_or_assign(2, 20); - cache.insert_or_assign(3, 30); - auto iter = cache.find(2); - // 2, 3, 1 - cache.find(3); - // 3, 2, 1 - iter = cache.erase(iter); - EXPECT_EQ(iter->first, 1); - EXPECT_EQ(iter->second, 10); - EXPECT_THAT(cache, ElementsAre(Pair(3, 30), Pair(1, 10))); -} - -TEST(LruCacheTest, erase_in_for_loop_test) { - LruCache<int, int> cache(3); - cache.insert_or_assign(1, 10); - cache.insert_or_assign(2, 20); - cache.insert_or_assign(3, 30); - for (auto iter = cache.begin(); iter != cache.end();) { - if (iter->first == 2) { - iter = cache.erase(iter); - } else { - ++iter; - } - } - EXPECT_THAT(cache, ElementsAre(Pair(3, 30), Pair(1, 10))); -} - -TEST(LruCacheTest, get_and_contains_key_test) { - LruCache<int, int> cache(3); // capacity = 3; - EXPECT_EQ(cache.size(), 0); - EXPECT_EQ(cache.find(42), cache.end()); - EXPECT_FALSE(cache.contains(42)); - EXPECT_FALSE(cache.insert_or_assign(56, 200)); - EXPECT_EQ(cache.find(42), cache.end()); - EXPECT_FALSE(cache.contains(42)); - EXPECT_NE(cache.find(56), cache.end()); - EXPECT_TRUE(cache.contains(56)); - auto iter = cache.find(56); - EXPECT_NE(iter, cache.end()); - EXPECT_EQ(iter->second, 200); - EXPECT_TRUE(cache.extract(56)); - EXPECT_FALSE(cache.contains(56)); -} - -TEST(LruCacheTest, put_and_get_sequence_1) { - // Section 1: Ordered put and ordered get - LruCache<int, int> cache(3); // capacity = 3; - EXPECT_FALSE(cache.insert_or_assign(1, 10)); - EXPECT_EQ(cache.size(), 1); - EXPECT_FALSE(cache.insert_or_assign(2, 20)); - EXPECT_EQ(cache.size(), 2); - EXPECT_FALSE(cache.insert_or_assign(3, 30)); - EXPECT_EQ(cache.size(), 3); - // 3, 2, 1 after above operations - - auto evicted = cache.insert_or_assign(4, 40); - // 4, 3, 2 after above operations, 1 is evicted - EXPECT_TRUE(evicted); - EXPECT_EQ(*evicted, std::make_pair(1, 10)); - EXPECT_EQ(cache.find(1), cache.end()); - LruCache<int, int>::const_iterator iter; - EXPECT_NE(iter = cache.find(4), cache.end()); - EXPECT_EQ(iter->second, 40); - EXPECT_NE(iter = cache.find(2), cache.end()); - EXPECT_EQ(iter->second, 20); - EXPECT_NE(iter = cache.find(3), cache.end()); - EXPECT_EQ(iter->second, 30); - // 3, 2, 4 after above operations - - // Section 2: Over capacity put and ordered get - evicted = cache.insert_or_assign(5, 50); - // 5, 3, 2 after above operations, 4 is evicted - EXPECT_EQ(cache.size(), 3); - EXPECT_TRUE(evicted); - EXPECT_EQ(*evicted, std::make_pair(4, 40)); - - EXPECT_TRUE(cache.extract(3)); - // 5, 2 should be in cache, 3 is removed - EXPECT_FALSE(cache.insert_or_assign(6, 60)); - // 6, 5, 2 should be in cache - - // Section 3: Out of order get - EXPECT_EQ(cache.find(3), cache.end()); - EXPECT_EQ(cache.find(4), cache.end()); - EXPECT_NE(iter = cache.find(2), cache.end()); - // 2, 6, 5 should be in cache - EXPECT_EQ(iter->second, 20); - EXPECT_NE(iter = cache.find(6), cache.end()); - // 6, 2, 5 should be in cache - EXPECT_EQ(iter->second, 60); - EXPECT_NE(iter = cache.find(5), cache.end()); - // 5, 6, 2 should be in cache - EXPECT_EQ(iter->second, 50); - evicted = cache.insert_or_assign(7, 70); - // 7, 5, 6 should be in cache, 2 is evicted - EXPECT_TRUE(evicted); - EXPECT_EQ(*evicted, std::make_pair(2, 20)); -} - -TEST(LruCacheTest, put_and_get_sequence_2) { - // Section 1: Replace item in cache - LruCache<int, int> cache(2); // size = 2; - EXPECT_FALSE(cache.insert_or_assign(1, 10)); - EXPECT_FALSE(cache.insert_or_assign(2, 20)); - // 2, 1 in cache - auto evicted = cache.insert_or_assign(3, 30); - // 3, 2 in cache, 1 is evicted - EXPECT_TRUE(evicted); - EXPECT_EQ(*evicted, std::make_pair(1, 10)); - EXPECT_FALSE(cache.insert_or_assign(2, 200)); - // 2, 3 in cache, nothing is evicted - EXPECT_EQ(cache.size(), 2); - - EXPECT_FALSE(cache.contains(1)); - LruCache<int, int>::const_iterator iter; - EXPECT_NE(iter = cache.find(2), cache.end()); - EXPECT_EQ(iter->second, 200); - EXPECT_NE(iter = cache.find(3), cache.end()); - // 3, 2 in cache - EXPECT_EQ(iter->second, 30); - - evicted = cache.insert_or_assign(4, 40); - // 4, 3 in cache, 2 is evicted - EXPECT_TRUE(evicted); - EXPECT_EQ(*evicted, std::make_pair(2, 200)); - - EXPECT_FALSE(cache.contains(2)); - EXPECT_NE(iter = cache.find(3), cache.end()); - EXPECT_EQ(iter->second, 30); - EXPECT_NE(iter = cache.find(4), cache.end()); - EXPECT_EQ(iter->second, 40); - // 4, 3 in cache - - EXPECT_TRUE(cache.extract(4)); - EXPECT_FALSE(cache.contains(4)); - // 3 in cache - EXPECT_EQ(cache.size(), 1); - EXPECT_FALSE(cache.insert_or_assign(2, 2000)); - // 2, 3 in cache - - EXPECT_FALSE(cache.contains(4)); - EXPECT_NE(iter = cache.find(3), cache.end()); - EXPECT_EQ(iter->second, 30); - EXPECT_NE(iter = cache.find(2), cache.end()); - EXPECT_EQ(iter->second, 2000); - - EXPECT_TRUE(cache.extract(2)); - EXPECT_TRUE(cache.extract(3)); - EXPECT_FALSE(cache.insert_or_assign(5, 50)); - EXPECT_FALSE(cache.insert_or_assign(1, 100)); - EXPECT_FALSE(cache.insert_or_assign(5, 1000)); - EXPECT_EQ(cache.size(), 2); - // 5, 1 in cache - - evicted = cache.insert_or_assign(6, 2000); - // 6, 5 in cache - EXPECT_TRUE(evicted); - EXPECT_EQ(*evicted, std::make_pair(1, 100)); - - EXPECT_FALSE(cache.contains(2)); - EXPECT_FALSE(cache.contains(3)); - EXPECT_NE(iter = cache.find(6), cache.end()); - EXPECT_EQ(iter->second, 2000); - EXPECT_NE(iter = cache.find(5), cache.end()); - EXPECT_EQ(iter->second, 1000); -} - -TEST(LruCacheTest, in_place_modification_test) { - LruCache<int, int> cache(2); - cache.insert_or_assign(1, 10); - cache.insert_or_assign(2, 20); - auto iter = cache.find(2); - ASSERT_THAT(cache, ElementsAre(Pair(2, 20), Pair(1, 10))); - iter->second = 200; - ASSERT_THAT(cache, ElementsAre(Pair(2, 200), Pair(1, 10))); - cache.insert_or_assign(1, 100); - // 1, 2 in cache - ASSERT_THAT(cache, ElementsAre(Pair(1, 100), Pair(2, 200))); - // modifying iterator does not warm up key - iter->second = 400; - ASSERT_THAT(cache, ElementsAre(Pair(1, 100), Pair(2, 400))); -} - -TEST(LruCacheTest, get_test) { - LruCache<int, int> cache(2); - EXPECT_FALSE(cache.insert_or_assign(1, 10)); - EXPECT_FALSE(cache.insert_or_assign(2, 20)); - EXPECT_TRUE(cache.contains(1)); - // 1, 2 in cache - auto evicted = cache.insert_or_assign(3, 30); - // 3, 1 in cache - EXPECT_TRUE(evicted); - EXPECT_EQ(*evicted, std::make_pair(2, 20)); -} - -TEST(LruCacheTest, remove_test) { - LruCache<int, int> cache(10); - for (int key = 0; key <= 30; key++) { - cache.insert_or_assign(key, key * 100); - } - for (int key = 0; key <= 20; key++) { - EXPECT_FALSE(cache.contains(key)); - } - for (int key = 21; key <= 30; key++) { - EXPECT_TRUE(cache.contains(key)); - } - for (int key = 0; key <= 20; key++) { - EXPECT_FALSE(cache.extract(key)); - } - for (int key = 21; key <= 30; key++) { - auto removed = cache.extract(key); - EXPECT_TRUE(removed); - EXPECT_EQ(*removed, std::make_pair(key, key * 100)); - } - for (int key = 21; key <= 30; key++) { - EXPECT_FALSE(cache.contains(key)); - } -} - -TEST(LruCacheTest, clear_test) { - LruCache<int, int> cache(10); - for (int key = 0; key < 10; key++) { - cache.insert_or_assign(key, key * 100); - } - for (int key = 0; key < 10; key++) { - EXPECT_TRUE(cache.contains(key)); - } - cache.clear(); - for (int key = 0; key < 10; key++) { - EXPECT_FALSE(cache.contains(key)); - } - - for (int key = 0; key < 10; key++) { - cache.insert_or_assign(key, key * 1000); - } - for (int key = 0; key < 10; key++) { - EXPECT_TRUE(cache.contains(key)); - } -} - -TEST(LruCacheTest, container_test) { - LruCache<int, int> lru_cache(2); - lru_cache.insert_or_assign(1, 10); - lru_cache.insert_or_assign(2, 20); - // Warm elements first - ASSERT_THAT(lru_cache, ElementsAre(Pair(2, 20), Pair(1, 10))); -} - -TEST(LruCacheTest, iterator_test) { - LruCache<int, int> lru_cache(2); - lru_cache.insert_or_assign(1, 10); - lru_cache.insert_or_assign(2, 20); - // Warm elements first - std::list<std::pair<int, int>> list(lru_cache.begin(), lru_cache.end()); - ASSERT_THAT(list, ElementsAre(Pair(2, 20), Pair(1, 10))); -} - -TEST(LruCacheTest, for_loop_test) { - LruCache<int, int> lru_cache(2); - lru_cache.insert_or_assign(1, 10); - lru_cache.insert_or_assign(2, 20); - // Warm elements first - std::list<std::pair<int, int>> list; - for (const auto& node : lru_cache) { - list.emplace_back(node); - } - ASSERT_THAT(list, ElementsAre(Pair(2, 20), Pair(1, 10))); - list.clear(); - for (auto& node : lru_cache) { - list.emplace_back(node); - node.second = node.second * 2; - } - ASSERT_THAT(list, ElementsAre(Pair(2, 20), Pair(1, 10))); - list.clear(); - for (const auto& node : lru_cache) { - list.emplace_back(node); - } - ASSERT_THAT(list, ElementsAre(Pair(2, 40), Pair(1, 20))); -} - -TEST(LruCacheTest, pressure_test) { - auto started = std::chrono::high_resolution_clock::now(); - int capacity = 0xFFFF; // 2^16 = 65535 - LruCache<int, int> cache(static_cast<size_t>(capacity)); - - // fill the cache - for (int key = 0; key < capacity; key++) { - cache.insert_or_assign(key, key); - } - - // make sure the cache is full - for (int key = 0; key < capacity; key++) { - EXPECT_TRUE(cache.contains(key)); - } - - // refresh the entire cache - for (int key = 0; key < capacity; key++) { - int new_key = key + capacity; - cache.insert_or_assign(new_key, new_key); - EXPECT_FALSE(cache.contains(key)); - EXPECT_TRUE(cache.contains(new_key)); - } - - // clear the entire cache - LruCache<int, int>::const_iterator iter; - for (int key = capacity; key < 2 * capacity; key++) { - EXPECT_NE(iter = cache.find(key), cache.end()); - EXPECT_EQ(iter->second, key); - EXPECT_TRUE(cache.extract(key)); - } - EXPECT_EQ(cache.size(), 0); - - // test execution time - auto done = std::chrono::high_resolution_clock::now(); - int execution_time = std::chrono::duration_cast<std::chrono::microseconds>(done - started).count(); - // Shouldn't be more than 1120ms - int execution_time_per_cycle_us = 17; - EXPECT_LT(execution_time, execution_time_per_cycle_us * capacity); -} - -} // namespace testing |