]> git.proxmox.com Git - ceph.git/blame - ceph/src/tools/immutable_object_cache/SimplePolicy.cc
Import ceph 15.2.8
[ceph.git] / ceph / src / tools / immutable_object_cache / SimplePolicy.cc
CommitLineData
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 "common/debug.h"
5#include "SimplePolicy.h"
6
7#define dout_context g_ceph_context
8#define dout_subsys ceph_subsys_immutable_obj_cache
9#undef dout_prefix
10#define dout_prefix *_dout << "ceph::cache::SimplePolicy: " << this << " " \
11 << __func__ << ": "
12
13namespace ceph {
14namespace immutable_obj_cache {
15
16SimplePolicy::SimplePolicy(CephContext *cct, uint64_t cache_size,
17 uint64_t max_inflight, double watermark)
18 : cct(cct), m_watermark(watermark), m_max_inflight_ops(max_inflight),
19 m_max_cache_size(cache_size) {
20
21 ldout(cct, 20) << "max cache size= " << m_max_cache_size
22 << " ,watermark= " << m_watermark
23 << " ,max inflight ops= " << m_max_inflight_ops << dendl;
24
25 m_cache_size = 0;
26
27}
28
29SimplePolicy::~SimplePolicy() {
30 ldout(cct, 20) << dendl;
31
32 for (auto it : m_cache_map) {
33 Entry* entry = (it.second);
34 delete entry;
35 }
36}
37
38cache_status_t SimplePolicy::alloc_entry(std::string file_name) {
39 ldout(cct, 20) << "alloc entry for: " << file_name << dendl;
40
41 std::unique_lock wlocker{m_cache_map_lock};
42
43 // cache hit when promoting
44 if (m_cache_map.find(file_name) != m_cache_map.end()) {
45 ldout(cct, 20) << "object is under promoting: " << file_name << dendl;
46 return OBJ_CACHE_SKIP;
47 }
48
49 if ((m_cache_size < m_max_cache_size) &&
50 (inflight_ops < m_max_inflight_ops)) {
51 Entry* entry = new Entry();
52 ceph_assert(entry != nullptr);
53 m_cache_map[file_name] = entry;
54 wlocker.unlock();
55 update_status(file_name, OBJ_CACHE_SKIP);
56 return OBJ_CACHE_NONE; // start promotion request
57 }
58
59 // if there's no free entry, return skip to read from rados
60 return OBJ_CACHE_SKIP;
61}
62
63cache_status_t SimplePolicy::lookup_object(std::string file_name) {
64 ldout(cct, 20) << "lookup: " << file_name << dendl;
65
66 std::shared_lock rlocker{m_cache_map_lock};
67
68 auto entry_it = m_cache_map.find(file_name);
69 // simply promote on first lookup
70 if (entry_it == m_cache_map.end()) {
71 rlocker.unlock();
72 return alloc_entry(file_name);
73 }
74
75 Entry* entry = entry_it->second;
76
f91f0fd5 77 if (entry->status == OBJ_CACHE_PROMOTED || entry->status == OBJ_CACHE_DNE) {
9f95a23c
TL
78 // bump pos in lru on hit
79 m_promoted_lru.lru_touch(entry);
80 }
81
82 return entry->status;
83}
84
85void SimplePolicy::update_status(std::string file_name,
86 cache_status_t new_status, uint64_t size) {
87 ldout(cct, 20) << "update status for: " << file_name
88 << " new status = " << new_status << dendl;
89
90 std::unique_lock locker{m_cache_map_lock};
91
92 auto entry_it = m_cache_map.find(file_name);
93 if (entry_it == m_cache_map.end()) {
94 return;
95 }
96
97 ceph_assert(entry_it != m_cache_map.end());
98 Entry* entry = entry_it->second;
99
100 // to promote
101 if (entry->status == OBJ_CACHE_NONE && new_status== OBJ_CACHE_SKIP) {
102 entry->status = new_status;
103 entry->file_name = file_name;
104 inflight_ops++;
105 return;
106 }
107
108 // promoting done
f91f0fd5
TL
109 if (entry->status == OBJ_CACHE_SKIP && (new_status== OBJ_CACHE_PROMOTED ||
110 new_status== OBJ_CACHE_DNE)) {
9f95a23c
TL
111 m_promoted_lru.lru_insert_top(entry);
112 entry->status = new_status;
113 entry->size = size;
114 m_cache_size += entry->size;
115 inflight_ops--;
116 return;
117 }
118
119 // promoting failed
120 if (entry->status == OBJ_CACHE_SKIP && new_status== OBJ_CACHE_NONE) {
121 // mark this entry as free
122 entry->file_name = "";
123 entry->status = new_status;
124
125 m_cache_map.erase(entry_it);
126 inflight_ops--;
127 delete entry;
128 return;
129 }
130
131 // to evict
f91f0fd5
TL
132 if ((entry->status == OBJ_CACHE_PROMOTED || entry->status == OBJ_CACHE_DNE) &&
133 new_status== OBJ_CACHE_NONE) {
9f95a23c
TL
134 // mark this entry as free
135 uint64_t size = entry->size;
136 entry->file_name = "";
137 entry->size = 0;
138 entry->status = new_status;
139
140 m_promoted_lru.lru_remove(entry);
141 m_cache_map.erase(entry_it);
142 m_cache_size -= size;
143 delete entry;
144 return;
145 }
146}
147
148int SimplePolicy::evict_entry(std::string file_name) {
149 ldout(cct, 20) << "to evict: " << file_name << dendl;
150
151 update_status(file_name, OBJ_CACHE_NONE);
152
153 return 0;
154}
155
156cache_status_t SimplePolicy::get_status(std::string file_name) {
157 ldout(cct, 20) << file_name << dendl;
158
159 std::shared_lock locker{m_cache_map_lock};
160 auto entry_it = m_cache_map.find(file_name);
161 if (entry_it == m_cache_map.end()) {
162 return OBJ_CACHE_NONE;
163 }
164
165 return entry_it->second->status;
166}
167
168void SimplePolicy::get_evict_list(std::list<std::string>* obj_list) {
169 ldout(cct, 20) << dendl;
170
171 std::unique_lock locker{m_cache_map_lock};
172 // check free ratio, pop entries from LRU
173 if ((double)m_cache_size / m_max_cache_size > (1 - m_watermark)) {
174 // TODO(dehao): make this configurable
175 int evict_num = m_cache_map.size() * 0.1;
176 for (int i = 0; i < evict_num; i++) {
177 Entry* entry = reinterpret_cast<Entry*>(m_promoted_lru.lru_expire());
178 if (entry == nullptr) {
179 continue;
180 }
181 std::string file_name = entry->file_name;
182 obj_list->push_back(file_name);
183 }
184 }
185}
186
187// for unit test
188uint64_t SimplePolicy::get_free_size() {
189 return m_max_cache_size - m_cache_size;
190}
191
192uint64_t SimplePolicy::get_promoting_entry_num() {
193 uint64_t index = 0;
194 std::shared_lock rlocker{m_cache_map_lock};
195 for (auto it : m_cache_map) {
196 if (it.second->status == OBJ_CACHE_SKIP) {
197 index++;
198 }
199 }
200 return index;
201}
202
203uint64_t SimplePolicy::get_promoted_entry_num() {
204 return m_promoted_lru.lru_get_size();
205}
206
207std::string SimplePolicy::get_evict_entry() {
208 Entry* entry = reinterpret_cast<Entry*>(m_promoted_lru.lru_get_next_expire());
209 if (entry == nullptr) {
210 return "";
211 }
212 return entry->file_name;
213}
214
215} // namespace immutable_obj_cache
216} // namespace ceph