]>
git.proxmox.com Git - ceph.git/blob - ceph/src/test/common/test_intrusive_lru.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
5 #include "gtest/gtest.h"
6 #include "common/intrusive_lru.h"
8 template <typename TestLRUItem
>
9 struct item_to_unsigned
{
10 using type
= unsigned;
11 const type
&operator()(const TestLRUItem
&item
) {
16 struct TestLRUItem
: public ceph::common::intrusive_lru_base
<
17 ceph::common::intrusive_lru_config
<
18 unsigned, TestLRUItem
, item_to_unsigned
<TestLRUItem
>>> {
22 TestLRUItem(unsigned key
) : key(key
) {}
25 class LRUTest
: public TestLRUItem::lru_t
{
27 auto add(unsigned int key
, int value
) {
28 auto [ref
, key_existed
] = get_or_create(key
);
32 return std::pair(ref
, key_existed
);
36 TEST(LRU
, add_immediate_evict
) {
42 auto [ref
, existed
] = cache
.add(key
, value1
);
44 ASSERT_EQ(value1
, ref
->value
);
45 ASSERT_FALSE(existed
);
48 auto [ref2
, existed
] = cache
.add(key
, value2
);
49 ASSERT_EQ(value2
, ref2
->value
);
50 ASSERT_FALSE(existed
);
54 TEST(LRU
, lookup_lru_size
) {
58 cache
.set_target_size(1);
60 auto [ref
, existed
] = cache
.add(key
, value
);
62 ASSERT_FALSE(existed
);
65 auto [ref
, existed
] = cache
.add(key
, value
);
69 cache
.set_target_size(0);
70 auto [ref2
, existed2
] = cache
.add(key
, value
);
72 ASSERT_FALSE(existed2
);
74 auto [ref
, existed
] = cache
.add(key
, value
);
81 const unsigned SIZE
= 3;
83 cache
.set_target_size(SIZE
);
85 for (unsigned i
= 0; i
< SIZE
; ++i
) {
86 auto [ref
, existed
] = cache
.add(i
, i
);
87 ASSERT_TRUE(ref
&& !existed
);
91 auto [ref
, existed
] = cache
.add(0, 0);
92 ASSERT_TRUE(ref
&& existed
);
95 for (unsigned i
= SIZE
; i
< (2*SIZE
) - 1; ++i
) {
96 auto [ref
, existed
] = cache
.add(i
, i
);
97 ASSERT_TRUE(ref
&& !existed
);
101 auto [ref
, existed
] = cache
.add(0, 0);
102 ASSERT_TRUE(ref
&& existed
);
105 for (unsigned i
= 1; i
< SIZE
; ++i
) {
106 auto [ref
, existed
] = cache
.add(i
, i
);
107 ASSERT_TRUE(ref
&& !existed
);
111 TEST(LRU
, eviction_live_ref
) {
112 const unsigned SIZE
= 3;
114 cache
.set_target_size(SIZE
);
116 auto [live_ref
, existed2
] = cache
.add(1, 1);
117 ASSERT_TRUE(live_ref
&& !existed2
);
119 for (unsigned i
= 0; i
< SIZE
; ++i
) {
120 auto [ref
, existed
] = cache
.add(i
, i
);
123 ASSERT_TRUE(existed
);
125 ASSERT_FALSE(existed
);
130 auto [ref
, existed
] = cache
.add(0, 0);
131 ASSERT_TRUE(ref
&& existed
);
134 for (unsigned i
= SIZE
; i
< (2*SIZE
) - 1; ++i
) {
135 auto [ref
, existed
] = cache
.add(i
, i
);
136 ASSERT_TRUE(ref
&& !existed
);
139 for (unsigned i
= 0; i
< SIZE
; ++i
) {
140 auto [ref
, existed
] = cache
.add(i
, i
);
143 ASSERT_TRUE(existed
);
145 ASSERT_FALSE(existed
);
150 TEST(LRU
, clear_range
) {
152 const unsigned SIZE
= 10;
153 cache
.set_target_size(SIZE
);
155 auto [ref
, existed
] = cache
.add(1, 4);
156 ASSERT_FALSE(existed
);
159 auto [ref
, existed
] = cache
.add(2, 4);
160 ASSERT_FALSE(existed
);
163 auto [ref
, existed
] = cache
.add(3, 4);
164 ASSERT_FALSE(existed
);
166 // Unlike above, the reference is not being destroyed
167 auto [live_ref1
, existed1
] = cache
.add(4, 4);
168 ASSERT_FALSE(existed1
);
170 auto [live_ref2
, existed2
] = cache
.add(5, 4);
171 ASSERT_FALSE(existed2
);
173 cache
.clear_range(0,4);
175 // Should not exists (Unreferenced):
177 auto [ref
, existed
] = cache
.add(1, 4);
178 ASSERT_FALSE(existed
);
181 auto [ref
, existed
] = cache
.add(2, 4);
182 ASSERT_FALSE(existed
);
185 auto [ref
, existed
] = cache
.add(3, 4);
186 ASSERT_FALSE(existed
);
188 // Should exist (Still being referenced):
190 auto [ref
, existed
] = cache
.add(4, 4);
191 ASSERT_TRUE(existed
);
193 // Should exists (Still being referenced and wasn't removed)
195 auto [ref
, existed
] = cache
.add(5, 4);
196 ASSERT_TRUE(existed
);
198 // Test out of bound deletion:
200 cache
.clear_range(3,8);
201 auto [ref
, existed
] = cache
.add(4, 4);
202 ASSERT_TRUE(existed
);
205 auto [ref
, existed
] = cache
.add(3, 4);
206 ASSERT_FALSE(existed
);