1#include <userver/multi-index-lru/container.hpp>
5#include <gtest/gtest.h>
6#include <boost/multi_index/hashed_index.hpp>
7#include <boost/multi_index/member.hpp>
13class LRUUsersTest :
public ::testing::Test {
15 void SetUp()
override {}
26 bool operator==(
const User& other)
const {
27 return id == other.id && email == other.email && name == other.name;
31 using UserCache = multi_index_lru::
Container<
33 boost::multi_index::indexed_by<
34 boost::multi_index::ordered_unique<
35 boost::multi_index::tag<IdTag>,
36 boost::multi_index::member<User,
int, &User::id>>,
37 boost::multi_index::ordered_unique<
38 boost::multi_index::tag<EmailTag>,
39 boost::multi_index::member<User, std::string, &User::email>>,
40 boost::multi_index::ordered_non_unique<
41 boost::multi_index::tag<NameTag>,
42 boost::multi_index::member<User, std::string, &User::name>>>>;
45TEST_F(LRUUsersTest, BasicOperations) {
49 cache.emplace(User{1,
"alice@test.com",
"Alice"});
50 cache.emplace(User{2,
"bob@test.com",
"Bob"});
51 cache.emplace(User{3,
"charlie@test.com",
"Charlie"});
53 EXPECT_EQ(cache.size(), 3);
56 auto by_id = cache.find<IdTag,
int>(1);
57 ASSERT_NE(by_id, cache.end<IdTag>());
58 EXPECT_EQ(by_id->name,
"Alice");
61 auto by_email = cache.find<EmailTag, std::string>(
"bob@test.com");
62 ASSERT_NE(by_email, cache.end<EmailTag>());
63 EXPECT_EQ(by_email->id, 2);
66 auto by_name = cache.find<NameTag, std::string>(
"Charlie");
67 ASSERT_NE(by_name, cache.end<NameTag>());
68 EXPECT_EQ(by_name->email,
"charlie@test.com");
71 auto it = cache.find<EmailTag, std::string>(
"alice@test.com");
72 EXPECT_NE(it, cache.end<EmailTag>());
75TEST_F(LRUUsersTest, LRUEviction) {
78 cache.emplace(User{1,
"alice@test.com",
"Alice"});
79 cache.emplace(User{2,
"bob@test.com",
"Bob"});
80 cache.emplace(User{3,
"charlie@test.com",
"Charlie"});
87 cache.emplace(User{4,
"david@test.com",
"David"});
89 EXPECT_FALSE((cache.contains<IdTag>(2)));
90 EXPECT_TRUE((cache.contains<IdTag>(1)));
91 EXPECT_TRUE((cache.contains<IdTag>(3)));
92 EXPECT_TRUE((cache.contains<IdTag>(4)));
95class ProductsTest :
public ::testing::Test {
105 bool operator==(
const Product& other)
const {
106 return sku == other.sku && name == other.name && price == other.price;
110 using ProductCache = multi_index_lru::
Container<
112 boost::multi_index::indexed_by<
113 boost::multi_index::ordered_unique<
114 boost::multi_index::tag<SkuTag>,
115 boost::multi_index::member<Product, std::string, &Product::sku>>,
116 boost::multi_index::ordered_unique<
117 boost::multi_index::tag<NameTag>,
118 boost::multi_index::member<Product, std::string, &Product::name>>>>;
121TEST_F(ProductsTest, BasicProductOperations) {
122 ProductCache cache(2);
124 cache.emplace(Product{
"A1",
"Laptop", 999.99});
125 cache.emplace(Product{
"A2",
"Mouse", 29.99});
127 auto laptop = cache.find<SkuTag, std::string>(
"A1");
128 ASSERT_NE(laptop, cache.end<SkuTag>());
129 EXPECT_EQ(laptop->name,
"Laptop");
132TEST_F(ProductsTest, ProductEviction) {
133 ProductCache cache(2);
135 cache.emplace(Product{
"A1",
"Laptop", 999.99});
136 cache.emplace(Product{
"A2",
"Mouse", 29.99});
139 cache.find<SkuTag>(
"A1");
140 cache.emplace(Product{
"A3",
"Keyboard", 79.99});
142 EXPECT_TRUE((cache.contains<SkuTag, std::string>(
"A1")));
143 EXPECT_TRUE((cache.contains<SkuTag, std::string>(
"A3")));
144 EXPECT_FALSE((cache.contains<SkuTag, std::string>(
"A2")));
146 EXPECT_NE(cache.find<NameTag>(
"Keyboard"), cache.end<NameTag>());
147 EXPECT_EQ(cache.find<NameTag>(
"Mouse"), cache.end<NameTag>());
150TEST(Snippet, SimpleUsage) {
158 MyValueT my_value{
"some_key", 1};
160 using MyLruCache = multi_index_lru::
Container<
162 boost::multi_index::indexed_by<boost::multi_index::hashed_unique<
163 boost::multi_index::tag<MyTag>,
164 boost::multi_index::member<MyValueT, std::string, &MyValueT::key>>>>;
166 MyLruCache cache(1000);
167 cache.insert(my_value);
168 auto it = cache.find<MyTag>(
"some_key");
169 EXPECT_NE(it, cache.end<MyTag>());