]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_cache.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
8 #define dout_subsys ceph_subsys_rgw
12 int ObjectCache::get(string
& name
, ObjectCacheInfo
& info
, uint32_t mask
, rgw_cache_entry_info
*cache_info
)
14 RWLock::RLocker
l(lock
);
20 auto iter
= cache_map
.find(name
);
21 if (iter
== cache_map
.end() ||
23 (ceph::coarse_mono_clock::now() - iter
->second
.info
.time_added
) > expiry
)) {
24 ldout(cct
, 10) << "cache get: name=" << name
<< " : miss" << dendl
;
26 perfcounter
->inc(l_rgw_cache_miss
);
30 ObjectCacheEntry
*entry
= &iter
->second
;
32 if (lru_counter
- entry
->lru_promotion_ts
> lru_window
) {
33 ldout(cct
, 20) << "cache get: touching lru, lru_counter=" << lru_counter
34 << " promotion_ts=" << entry
->lru_promotion_ts
<< dendl
;
36 lock
.get_write(); /* promote lock to writer */
38 /* need to redo this because entry might have dropped off the cache */
39 iter
= cache_map
.find(name
);
40 if (iter
== cache_map
.end()) {
41 ldout(cct
, 10) << "lost race! cache get: name=" << name
<< " : miss" << dendl
;
42 if(perfcounter
) perfcounter
->inc(l_rgw_cache_miss
);
46 entry
= &iter
->second
;
47 /* check again, we might have lost a race here */
48 if (lru_counter
- entry
->lru_promotion_ts
> lru_window
) {
49 touch_lru(name
, *entry
, iter
->second
.lru_iter
);
53 ObjectCacheInfo
& src
= iter
->second
.info
;
54 if ((src
.flags
& mask
) != mask
) {
55 ldout(cct
, 10) << "cache get: name=" << name
<< " : type miss (requested=0x"
56 << std::hex
<< mask
<< ", cached=0x" << src
.flags
57 << std::dec
<< ")" << dendl
;
58 if(perfcounter
) perfcounter
->inc(l_rgw_cache_miss
);
61 ldout(cct
, 10) << "cache get: name=" << name
<< " : hit (requested=0x"
62 << std::hex
<< mask
<< ", cached=0x" << src
.flags
63 << std::dec
<< ")" << dendl
;
67 cache_info
->cache_locator
= name
;
68 cache_info
->gen
= entry
->gen
;
70 if(perfcounter
) perfcounter
->inc(l_rgw_cache_hit
);
75 bool ObjectCache::chain_cache_entry(list
<rgw_cache_entry_info
*>& cache_info_entries
, RGWChainedCache::Entry
*chained_entry
)
77 RWLock::WLocker
l(lock
);
83 list
<rgw_cache_entry_info
*>::iterator citer
;
85 list
<ObjectCacheEntry
*> cache_entry_list
;
87 /* first verify that all entries are still valid */
88 for (citer
= cache_info_entries
.begin(); citer
!= cache_info_entries
.end(); ++citer
) {
89 rgw_cache_entry_info
*cache_info
= *citer
;
91 ldout(cct
, 10) << "chain_cache_entry: cache_locator=" << cache_info
->cache_locator
<< dendl
;
92 map
<string
, ObjectCacheEntry
>::iterator iter
= cache_map
.find(cache_info
->cache_locator
);
93 if (iter
== cache_map
.end()) {
94 ldout(cct
, 20) << "chain_cache_entry: couldn't find cache locator" << dendl
;
98 ObjectCacheEntry
*entry
= &iter
->second
;
100 if (entry
->gen
!= cache_info
->gen
) {
101 ldout(cct
, 20) << "chain_cache_entry: entry.gen (" << entry
->gen
<< ") != cache_info.gen (" << cache_info
->gen
<< ")" << dendl
;
105 cache_entry_list
.push_back(entry
);
109 chained_entry
->cache
->chain_cb(chained_entry
->key
, chained_entry
->data
);
111 list
<ObjectCacheEntry
*>::iterator liter
;
113 for (liter
= cache_entry_list
.begin(); liter
!= cache_entry_list
.end(); ++liter
) {
114 ObjectCacheEntry
*entry
= *liter
;
116 entry
->chained_entries
.push_back(make_pair(chained_entry
->cache
, chained_entry
->key
));
122 void ObjectCache::put(string
& name
, ObjectCacheInfo
& info
, rgw_cache_entry_info
*cache_info
)
124 RWLock::WLocker
l(lock
);
130 ldout(cct
, 10) << "cache put: name=" << name
<< " info.flags=0x"
131 << std::hex
<< info
.flags
<< std::dec
<< dendl
;
132 map
<string
, ObjectCacheEntry
>::iterator iter
= cache_map
.find(name
);
133 if (iter
== cache_map
.end()) {
134 ObjectCacheEntry entry
;
135 entry
.lru_iter
= lru
.end();
136 cache_map
.insert(pair
<string
, ObjectCacheEntry
>(name
, entry
));
137 iter
= cache_map
.find(name
);
139 ObjectCacheEntry
& entry
= iter
->second
;
140 ObjectCacheInfo
& target
= entry
.info
;
142 invalidate_lru(entry
);
144 entry
.chained_entries
.clear();
147 touch_lru(name
, entry
, entry
.lru_iter
);
149 target
.status
= info
.status
;
151 if (info
.status
< 0) {
153 target
.xattrs
.clear();
159 cache_info
->cache_locator
= name
;
160 cache_info
->gen
= entry
.gen
;
163 target
.flags
|= info
.flags
;
165 if (info
.flags
& CACHE_FLAG_META
)
166 target
.meta
= info
.meta
;
167 else if (!(info
.flags
& CACHE_FLAG_MODIFY_XATTRS
))
168 target
.flags
&= ~CACHE_FLAG_META
; // non-meta change should reset meta
170 if (info
.flags
& CACHE_FLAG_XATTRS
) {
171 target
.xattrs
= info
.xattrs
;
172 map
<string
, bufferlist
>::iterator iter
;
173 for (iter
= target
.xattrs
.begin(); iter
!= target
.xattrs
.end(); ++iter
) {
174 ldout(cct
, 10) << "updating xattr: name=" << iter
->first
<< " bl.length()=" << iter
->second
.length() << dendl
;
176 } else if (info
.flags
& CACHE_FLAG_MODIFY_XATTRS
) {
177 map
<string
, bufferlist
>::iterator iter
;
178 for (iter
= info
.rm_xattrs
.begin(); iter
!= info
.rm_xattrs
.end(); ++iter
) {
179 ldout(cct
, 10) << "removing xattr: name=" << iter
->first
<< dendl
;
180 target
.xattrs
.erase(iter
->first
);
182 for (iter
= info
.xattrs
.begin(); iter
!= info
.xattrs
.end(); ++iter
) {
183 ldout(cct
, 10) << "appending xattr: name=" << iter
->first
<< " bl.length()=" << iter
->second
.length() << dendl
;
184 target
.xattrs
[iter
->first
] = iter
->second
;
188 if (info
.flags
& CACHE_FLAG_DATA
)
189 target
.data
= info
.data
;
191 if (info
.flags
& CACHE_FLAG_OBJV
)
192 target
.version
= info
.version
;
195 void ObjectCache::remove(string
& name
)
197 RWLock::WLocker
l(lock
);
203 map
<string
, ObjectCacheEntry
>::iterator iter
= cache_map
.find(name
);
204 if (iter
== cache_map
.end())
207 ldout(cct
, 10) << "removing " << name
<< " from cache" << dendl
;
208 ObjectCacheEntry
& entry
= iter
->second
;
210 for (list
<pair
<RGWChainedCache
*, string
> >::iterator iiter
= entry
.chained_entries
.begin();
211 iiter
!= entry
.chained_entries
.end(); ++iiter
) {
212 RGWChainedCache
*chained_cache
= iiter
->first
;
213 chained_cache
->invalidate(iiter
->second
);
216 remove_lru(name
, iter
->second
.lru_iter
);
217 cache_map
.erase(iter
);
220 void ObjectCache::touch_lru(string
& name
, ObjectCacheEntry
& entry
, std::list
<string
>::iterator
& lru_iter
)
222 while (lru_size
> (size_t)cct
->_conf
->rgw_cache_lru_size
) {
223 list
<string
>::iterator iter
= lru
.begin();
224 if ((*iter
).compare(name
) == 0) {
226 * if the entry we're touching happens to be at the lru end, don't remove it,
227 * lru shrinking can wait for next time
231 map
<string
, ObjectCacheEntry
>::iterator map_iter
= cache_map
.find(*iter
);
232 ldout(cct
, 10) << "removing entry: name=" << *iter
<< " from cache LRU" << dendl
;
233 if (map_iter
!= cache_map
.end()) {
234 ObjectCacheEntry
& entry
= map_iter
->second
;
235 invalidate_lru(entry
);
236 cache_map
.erase(map_iter
);
242 if (lru_iter
== lru
.end()) {
246 ldout(cct
, 10) << "adding " << name
<< " to cache LRU end" << dendl
;
248 ldout(cct
, 10) << "moving " << name
<< " to cache LRU end" << dendl
;
251 lru_iter
= lru
.end();
256 entry
.lru_promotion_ts
= lru_counter
;
259 void ObjectCache::remove_lru(string
& name
, std::list
<string
>::iterator
& lru_iter
)
261 if (lru_iter
== lru
.end())
266 lru_iter
= lru
.end();
269 void ObjectCache::invalidate_lru(ObjectCacheEntry
& entry
)
271 for (list
<pair
<RGWChainedCache
*, string
> >::iterator iter
= entry
.chained_entries
.begin();
272 iter
!= entry
.chained_entries
.end(); ++iter
) {
273 RGWChainedCache
*chained_cache
= iter
->first
;
274 chained_cache
->invalidate(iter
->second
);
278 void ObjectCache::set_enabled(bool status
)
280 RWLock::WLocker
l(lock
);
289 void ObjectCache::invalidate_all()
291 RWLock::WLocker
l(lock
);
296 void ObjectCache::do_invalidate_all()
305 for (list
<RGWChainedCache
*>::iterator iter
= chained_cache
.begin(); iter
!= chained_cache
.end(); ++iter
) {
306 (*iter
)->invalidate_all();
310 void ObjectCache::chain_cache(RGWChainedCache
*cache
) {
311 RWLock::WLocker
l(lock
);
312 chained_cache
.push_back(cache
);