1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
|
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
#include <sstream>
#include <list>
#include <gtest/gtest.h>
#include "include/Context.h"
#include "tools/immutable_object_cache/SimplePolicy.h"
using namespace ceph::immutable_obj_cache;
std::string generate_file_name(uint64_t index) {
std::string pre_name("object_cache_file_");
std::ostringstream oss;
oss << index;
return pre_name + oss.str();
}
class TestSimplePolicy :public ::testing::Test {
public:
SimplePolicy* m_simple_policy;
const uint64_t m_cache_size;
uint64_t m_entry_index;
std::vector<std::string> m_promoted_lru;
std::vector<std::string> m_promoting_lru;
TestSimplePolicy() : m_cache_size(100), m_entry_index(0) {}
~TestSimplePolicy() {}
static void SetUpTestCase() {}
static void TearDownTestCase() {}
void SetUp() override {
m_simple_policy = new SimplePolicy(g_ceph_context, m_cache_size, 128, 0.9);
// populate 50 entries
for (uint64_t i = 0; i < m_cache_size / 2; i++, m_entry_index++) {
insert_entry_into_promoted_lru(generate_file_name(m_entry_index));
}
}
void TearDown() override {
while(m_promoted_lru.size()) {
ASSERT_TRUE(m_simple_policy->get_evict_entry() == m_promoted_lru.front());
m_simple_policy->evict_entry(m_simple_policy->get_evict_entry());
m_promoted_lru.erase(m_promoted_lru.begin());
}
delete m_simple_policy;
}
void insert_entry_into_promoted_lru(std::string cache_file_name) {
ASSERT_EQ(m_cache_size - m_promoted_lru.size(), m_simple_policy->get_free_size());
ASSERT_EQ(m_promoting_lru.size(), m_simple_policy->get_promoting_entry_num());
ASSERT_EQ(m_promoted_lru.size(), m_simple_policy->get_promoted_entry_num());
ASSERT_EQ(OBJ_CACHE_NONE, m_simple_policy->get_status(cache_file_name));
m_simple_policy->lookup_object(cache_file_name);
ASSERT_EQ(OBJ_CACHE_SKIP, m_simple_policy->get_status(cache_file_name));
ASSERT_EQ(m_cache_size - m_promoted_lru.size(), m_simple_policy->get_free_size());
ASSERT_EQ(m_promoting_lru.size() + 1, m_simple_policy->get_promoting_entry_num());
ASSERT_EQ(m_promoted_lru.size(), m_simple_policy->get_promoted_entry_num());
m_simple_policy->update_status(cache_file_name, OBJ_CACHE_PROMOTED, 1);
m_promoted_lru.push_back(cache_file_name);
ASSERT_EQ(OBJ_CACHE_PROMOTED, m_simple_policy->get_status(cache_file_name));
ASSERT_EQ(m_cache_size - m_promoted_lru.size(), m_simple_policy->get_free_size());
ASSERT_EQ(m_promoting_lru.size(), m_simple_policy->get_promoting_entry_num());
ASSERT_EQ(m_promoted_lru.size(), m_simple_policy->get_promoted_entry_num());
}
void insert_entry_into_promoting_lru(std::string cache_file_name) {
ASSERT_EQ(m_cache_size - m_promoted_lru.size(), m_simple_policy->get_free_size());
ASSERT_EQ(m_promoting_lru.size(), m_simple_policy->get_promoting_entry_num());
ASSERT_EQ(m_promoted_lru.size(), m_simple_policy->get_promoted_entry_num());
ASSERT_EQ(OBJ_CACHE_NONE, m_simple_policy->get_status(cache_file_name));
m_simple_policy->lookup_object(cache_file_name);
m_promoting_lru.push_back(cache_file_name);
ASSERT_EQ(OBJ_CACHE_SKIP, m_simple_policy->get_status(cache_file_name));
ASSERT_EQ(m_cache_size - m_promoted_lru.size(), m_simple_policy->get_free_size());
ASSERT_EQ(m_promoting_lru.size(), m_simple_policy->get_promoting_entry_num());
ASSERT_EQ(m_promoted_lru.size(), m_simple_policy->get_promoted_entry_num());
}
};
TEST_F(TestSimplePolicy, test_lookup_miss_and_no_free) {
// exhaust cache space
uint64_t left_entry_num = m_cache_size - m_promoted_lru.size();
for (uint64_t i = 0; i < left_entry_num; i++, ++m_entry_index) {
insert_entry_into_promoted_lru(generate_file_name(m_entry_index));
}
ASSERT_TRUE(0 == m_simple_policy->get_free_size());
ASSERT_TRUE(m_simple_policy->lookup_object("no_this_cache_file_name") == OBJ_CACHE_SKIP);
}
TEST_F(TestSimplePolicy, test_lookup_miss_and_have_free) {
ASSERT_TRUE(m_cache_size - m_promoted_lru.size() == m_simple_policy->get_free_size());
ASSERT_TRUE(m_simple_policy->lookup_object("miss_but_have_free_space_file_name") == OBJ_CACHE_NONE);
ASSERT_TRUE(m_simple_policy->get_status("miss_but_have_free_space_file_name") == OBJ_CACHE_SKIP);
}
TEST_F(TestSimplePolicy, test_lookup_hit_and_promoting) {
ASSERT_TRUE(m_cache_size - m_promoted_lru.size() == m_simple_policy->get_free_size());
insert_entry_into_promoting_lru("promoting_file_1");
insert_entry_into_promoting_lru("promoting_file_2");
insert_entry_into_promoted_lru(generate_file_name(++m_entry_index));
insert_entry_into_promoted_lru(generate_file_name(++m_entry_index));
insert_entry_into_promoting_lru("promoting_file_3");
insert_entry_into_promoting_lru("promoting_file_4");
ASSERT_TRUE(m_simple_policy->get_promoting_entry_num() == 4);
ASSERT_TRUE(m_simple_policy->get_status("promoting_file_1") == OBJ_CACHE_SKIP);
ASSERT_TRUE(m_simple_policy->get_status("promoting_file_2") == OBJ_CACHE_SKIP);
ASSERT_TRUE(m_simple_policy->get_status("promoting_file_3") == OBJ_CACHE_SKIP);
ASSERT_TRUE(m_simple_policy->get_status("promoting_file_4") == OBJ_CACHE_SKIP);
ASSERT_TRUE(m_simple_policy->lookup_object("promoting_file_1") == OBJ_CACHE_SKIP);
ASSERT_TRUE(m_simple_policy->lookup_object("promoting_file_2") == OBJ_CACHE_SKIP);
ASSERT_TRUE(m_simple_policy->lookup_object("promoting_file_3") == OBJ_CACHE_SKIP);
ASSERT_TRUE(m_simple_policy->lookup_object("promoting_file_4") == OBJ_CACHE_SKIP);
}
TEST_F(TestSimplePolicy, test_lookup_hit_and_promoted) {
ASSERT_TRUE(m_promoted_lru.size() == m_simple_policy->get_promoted_entry_num());
for (uint64_t index = 0; index < m_entry_index; index++) {
ASSERT_TRUE(m_simple_policy->get_status(generate_file_name(index)) == OBJ_CACHE_PROMOTED);
}
}
TEST_F(TestSimplePolicy, test_update_state_from_promoting_to_none) {
ASSERT_TRUE(m_cache_size - m_promoted_lru.size() == m_simple_policy->get_free_size());
insert_entry_into_promoting_lru("promoting_to_none_file_1");
insert_entry_into_promoting_lru("promoting_to_none_file_2");
insert_entry_into_promoted_lru(generate_file_name(++m_entry_index));
insert_entry_into_promoting_lru("promoting_to_none_file_3");
insert_entry_into_promoting_lru("promoting_to_none_file_4");
ASSERT_TRUE(m_simple_policy->get_promoting_entry_num() == 4);
ASSERT_TRUE(m_simple_policy->get_status("promoting_to_none_file_1") == OBJ_CACHE_SKIP);
ASSERT_TRUE(m_simple_policy->get_status("promoting_to_none_file_2") == OBJ_CACHE_SKIP);
ASSERT_TRUE(m_simple_policy->get_status("promoting_to_none_file_3") == OBJ_CACHE_SKIP);
ASSERT_TRUE(m_simple_policy->get_status("promoting_to_none_file_4") == OBJ_CACHE_SKIP);
m_simple_policy->update_status("promoting_to_none_file_1", OBJ_CACHE_NONE);
ASSERT_TRUE(m_simple_policy->get_promoting_entry_num() == 3);
ASSERT_TRUE(m_simple_policy->get_status("promoting_to_none_file_1") == OBJ_CACHE_NONE);
ASSERT_TRUE(m_simple_policy->get_status("promoting_to_none_file_2") == OBJ_CACHE_SKIP);
ASSERT_TRUE(m_simple_policy->get_status("promoting_to_none_file_3") == OBJ_CACHE_SKIP);
ASSERT_TRUE(m_simple_policy->get_status("promoting_to_none_file_4") == OBJ_CACHE_SKIP);
m_simple_policy->update_status("promoting_to_none_file_2", OBJ_CACHE_NONE);
ASSERT_TRUE(m_simple_policy->get_promoting_entry_num() == 2);
ASSERT_TRUE(m_simple_policy->get_status("promoting_to_none_file_1") == OBJ_CACHE_NONE);
ASSERT_TRUE(m_simple_policy->get_status("promoting_to_none_file_2") == OBJ_CACHE_NONE);
ASSERT_TRUE(m_simple_policy->get_status("promoting_to_none_file_3") == OBJ_CACHE_SKIP);
ASSERT_TRUE(m_simple_policy->get_status("promoting_to_none_file_4") == OBJ_CACHE_SKIP);
m_simple_policy->update_status("promoting_to_none_file_3", OBJ_CACHE_NONE);
ASSERT_TRUE(m_simple_policy->get_promoting_entry_num() == 1);
ASSERT_TRUE(m_simple_policy->get_status("promoting_to_none_file_1") == OBJ_CACHE_NONE);
ASSERT_TRUE(m_simple_policy->get_status("promoting_to_none_file_2") == OBJ_CACHE_NONE);
ASSERT_TRUE(m_simple_policy->get_status("promoting_to_none_file_3") == OBJ_CACHE_NONE);
ASSERT_TRUE(m_simple_policy->get_status("promoting_to_none_file_4") == OBJ_CACHE_SKIP);
m_simple_policy->update_status("promoting_to_none_file_4", OBJ_CACHE_NONE);
ASSERT_TRUE(m_simple_policy->get_promoting_entry_num() == 0);
ASSERT_TRUE(m_simple_policy->get_status("promoting_to_none_file_1") == OBJ_CACHE_NONE);
ASSERT_TRUE(m_simple_policy->get_status("promoting_to_none_file_2") == OBJ_CACHE_NONE);
ASSERT_TRUE(m_simple_policy->get_status("promoting_to_none_file_3") == OBJ_CACHE_NONE);
ASSERT_TRUE(m_simple_policy->get_status("promoting_to_none_file_4") == OBJ_CACHE_NONE);
}
TEST_F(TestSimplePolicy, test_update_state_from_promoted_to_none) {
ASSERT_TRUE(m_promoted_lru.size() == m_simple_policy->get_promoted_entry_num());
for (uint64_t index = 0; index < m_entry_index; index++) {
ASSERT_TRUE(m_simple_policy->get_status(generate_file_name(index)) == OBJ_CACHE_PROMOTED);
m_simple_policy->update_status(generate_file_name(index), OBJ_CACHE_NONE);
ASSERT_TRUE(m_simple_policy->get_status(generate_file_name(index)) == OBJ_CACHE_NONE);
ASSERT_TRUE(m_simple_policy->get_promoted_entry_num() == m_promoted_lru.size() - index - 1);
}
m_promoted_lru.clear();
}
TEST_F(TestSimplePolicy, test_update_state_from_promoting_to_promoted) {
ASSERT_TRUE(m_cache_size - m_promoted_lru.size() == m_simple_policy->get_free_size());
insert_entry_into_promoting_lru("promoting_to_promoted_file_1");
insert_entry_into_promoting_lru("promoting_to_promoted_file_2");
insert_entry_into_promoting_lru("promoting_to_promoted_file_3");
insert_entry_into_promoting_lru("promoting_to_promoted_file_4");
ASSERT_TRUE(4 == m_simple_policy->get_promoting_entry_num());
m_simple_policy->update_status("promoting_to_promoted_file_1", OBJ_CACHE_PROMOTED);
ASSERT_TRUE(3 == m_simple_policy->get_promoting_entry_num());
ASSERT_TRUE(m_simple_policy->get_status("promoting_to_promoted_file_1") == OBJ_CACHE_PROMOTED);
m_simple_policy->update_status("promoting_to_promoted_file_2", OBJ_CACHE_PROMOTED);
ASSERT_TRUE(2 == m_simple_policy->get_promoting_entry_num());
ASSERT_TRUE(m_simple_policy->get_status("promoting_to_promoted_file_2") == OBJ_CACHE_PROMOTED);
m_simple_policy->update_status("promoting_to_promoted_file_3", OBJ_CACHE_PROMOTED);
ASSERT_TRUE(1 == m_simple_policy->get_promoting_entry_num());
ASSERT_TRUE(m_simple_policy->get_status("promoting_to_promoted_file_3") == OBJ_CACHE_PROMOTED);
m_simple_policy->update_status("promoting_to_promoted_file_4", OBJ_CACHE_PROMOTED);
ASSERT_TRUE(0 == m_simple_policy->get_promoting_entry_num());
ASSERT_TRUE(m_simple_policy->get_status("promoting_to_promoted_file_4") == OBJ_CACHE_PROMOTED);
m_promoted_lru.push_back("promoting_to_promoted_file_1");
m_promoted_lru.push_back("promoting_to_promoted_file_2");
m_promoted_lru.push_back("promoting_to_promoted_file_3");
m_promoted_lru.push_back("promoting_to_promoted_file_4");
}
TEST_F(TestSimplePolicy, test_evict_list_0) {
std::list<std::string> evict_entry_list;
// the default water mark is 0.9
ASSERT_TRUE((float)m_simple_policy->get_free_size() > m_cache_size*0.1);
m_simple_policy->get_evict_list(&evict_entry_list);
ASSERT_TRUE(evict_entry_list.size() == 0);
}
TEST_F(TestSimplePolicy, test_evict_list_10) {
uint64_t left_entry_num = m_cache_size - m_promoted_lru.size();
for (uint64_t i = 0; i < left_entry_num; i++, ++m_entry_index) {
insert_entry_into_promoted_lru(generate_file_name(m_entry_index));
}
ASSERT_TRUE(0 == m_simple_policy->get_free_size());
std::list<std::string> evict_entry_list;
m_simple_policy->get_evict_list(&evict_entry_list);
// evict 10% of old entries
ASSERT_TRUE(m_cache_size*0.1 == evict_entry_list.size());
ASSERT_TRUE(m_cache_size - m_cache_size*0.1 == m_simple_policy->get_promoted_entry_num());
for (auto it = evict_entry_list.begin(); it != evict_entry_list.end(); it++) {
ASSERT_TRUE(*it == m_promoted_lru.front());
m_promoted_lru.erase(m_promoted_lru.begin());
}
}
|