summaryrefslogtreecommitdiffstats
path: root/src/test/immutable_object_cache/test_SimplePolicy.cc
blob: 26f503be4f7fc204571d0d4b4be79a92e419c52d (plain)
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());
  }
}