]>
Commit | Line | Data |
---|---|---|
9f95a23c TL |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #include <stdio.h> | |
5 | #include "gtest/gtest.h" | |
6 | #include "common/intrusive_lru.h" | |
7 | ||
8 | template <typename TestLRUItem> | |
9 | struct item_to_unsigned { | |
10 | using type = unsigned; | |
11 | const type &operator()(const TestLRUItem &item) { | |
12 | return item.key; | |
13 | } | |
14 | }; | |
15 | ||
16 | struct TestLRUItem : public ceph::common::intrusive_lru_base< | |
17 | ceph::common::intrusive_lru_config< | |
18 | unsigned, TestLRUItem, item_to_unsigned<TestLRUItem>>> { | |
19 | unsigned key = 0; | |
20 | int value = 0; | |
21 | bool seen = false; | |
22 | ||
23 | TestLRUItem(unsigned key) : key(key) {} | |
24 | }; | |
25 | ||
26 | class LRUTest : public TestLRUItem::lru_t { | |
27 | public: | |
28 | auto add(unsigned int key, int value) { | |
29 | auto [ref, key_existed] = get_or_create(key); | |
30 | if (!key_existed) { | |
31 | ref->value = value; | |
32 | } | |
33 | return std::pair(ref, key_existed); | |
34 | } | |
35 | }; | |
36 | ||
37 | TEST(LRU, add_immediate_evict) { | |
38 | LRUTest cache; | |
39 | unsigned int key = 1; | |
40 | int value1 = 2; | |
41 | int value2 = 3; | |
42 | { | |
43 | auto [ref, existed] = cache.add(key, value1); | |
44 | ASSERT_TRUE(ref); | |
45 | ASSERT_EQ(value1, ref->value); | |
46 | ASSERT_FALSE(existed); | |
47 | } | |
48 | { | |
49 | auto [ref2, existed] = cache.add(key, value2); | |
50 | ASSERT_EQ(value2, ref2->value); | |
51 | ASSERT_FALSE(existed); | |
52 | } | |
53 | } | |
54 | ||
55 | TEST(LRU, lookup_lru_size) { | |
56 | LRUTest cache; | |
57 | int key = 1; | |
58 | int value = 1; | |
59 | cache.set_target_size(1); | |
60 | { | |
61 | auto [ref, existed] = cache.add(key, value); | |
62 | ASSERT_TRUE(ref); | |
63 | ASSERT_FALSE(existed); | |
64 | } | |
65 | { | |
66 | auto [ref, existed] = cache.add(key, value); | |
67 | ASSERT_TRUE(ref); | |
68 | ASSERT_TRUE(existed); | |
69 | } | |
70 | cache.set_target_size(0); | |
71 | auto [ref2, existed2] = cache.add(key, value); | |
72 | ASSERT_TRUE(ref2); | |
73 | ASSERT_FALSE(existed2); | |
74 | { | |
75 | auto [ref, existed] = cache.add(key, value); | |
76 | ASSERT_TRUE(ref); | |
77 | ASSERT_TRUE(existed); | |
78 | } | |
79 | } | |
80 | ||
81 | TEST(LRU, eviction) { | |
82 | const unsigned SIZE = 3; | |
83 | LRUTest cache; | |
84 | cache.set_target_size(SIZE); | |
85 | ||
86 | for (unsigned i = 0; i < SIZE; ++i) { | |
87 | auto [ref, existed] = cache.add(i, i); | |
88 | ASSERT_TRUE(ref && !existed); | |
89 | } | |
90 | ||
91 | { | |
92 | auto [ref, existed] = cache.add(0, 0); | |
93 | ASSERT_TRUE(ref && existed); | |
94 | } | |
95 | ||
96 | for (unsigned i = SIZE; i < (2*SIZE) - 1; ++i) { | |
97 | auto [ref, existed] = cache.add(i, i); | |
98 | ASSERT_TRUE(ref && !existed); | |
99 | } | |
100 | ||
101 | { | |
102 | auto [ref, existed] = cache.add(0, 0); | |
103 | ASSERT_TRUE(ref && existed); | |
104 | } | |
105 | ||
106 | for (unsigned i = 1; i < SIZE; ++i) { | |
107 | auto [ref, existed] = cache.add(i, i); | |
108 | ASSERT_TRUE(ref && !existed); | |
109 | } | |
110 | } | |
111 | ||
112 | TEST(LRU, eviction_live_ref) { | |
113 | const unsigned SIZE = 3; | |
114 | LRUTest cache; | |
115 | cache.set_target_size(SIZE); | |
116 | ||
117 | auto [live_ref, existed2] = cache.add(1, 1); | |
118 | ASSERT_TRUE(live_ref && !existed2); | |
119 | ||
120 | for (unsigned i = 0; i < SIZE; ++i) { | |
121 | auto [ref, existed] = cache.add(i, i); | |
122 | ASSERT_TRUE(ref); | |
123 | if (i == 1) { | |
124 | ASSERT_TRUE(existed); | |
125 | } else { | |
126 | ASSERT_FALSE(existed); | |
127 | } | |
128 | } | |
129 | ||
130 | { | |
131 | auto [ref, existed] = cache.add(0, 0); | |
132 | ASSERT_TRUE(ref && existed); | |
133 | } | |
134 | ||
135 | for (unsigned i = SIZE; i < (2*SIZE) - 1; ++i) { | |
136 | auto [ref, existed] = cache.add(i, i); | |
137 | ASSERT_TRUE(ref && !existed); | |
138 | } | |
139 | ||
140 | for (unsigned i = 0; i < SIZE; ++i) { | |
141 | auto [ref, existed] = cache.add(i, i); | |
142 | ASSERT_TRUE(ref); | |
143 | if (i == 1) { | |
144 | ASSERT_TRUE(existed); | |
145 | } else { | |
146 | ASSERT_FALSE(existed); | |
147 | } | |
148 | } | |
149 | } |