]>
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 map
<string
, ObjectCacheEntry
>::iterator iter
= cache_map
.find(name
);
21 if (iter
== cache_map
.end()) {
22 ldout(cct
, 10) << "cache get: name=" << name
<< " : miss" << dendl
;
23 if(perfcounter
) perfcounter
->inc(l_rgw_cache_miss
);
27 ObjectCacheEntry
*entry
= &iter
->second
;
29 if (lru_counter
- entry
->lru_promotion_ts
> lru_window
) {
30 ldout(cct
, 20) << "cache get: touching lru, lru_counter=" << lru_counter
31 << " promotion_ts=" << entry
->lru_promotion_ts
<< dendl
;
33 lock
.get_write(); /* promote lock to writer */
35 /* need to redo this because entry might have dropped off the cache */
36 iter
= cache_map
.find(name
);
37 if (iter
== cache_map
.end()) {
38 ldout(cct
, 10) << "lost race! cache get: name=" << name
<< " : miss" << dendl
;
39 if(perfcounter
) perfcounter
->inc(l_rgw_cache_miss
);
43 entry
= &iter
->second
;
44 /* check again, we might have lost a race here */
45 if (lru_counter
- entry
->lru_promotion_ts
> lru_window
) {
46 touch_lru(name
, *entry
, iter
->second
.lru_iter
);
50 ObjectCacheInfo
& src
= iter
->second
.info
;
51 if ((src
.flags
& mask
) != mask
) {
52 ldout(cct
, 10) << "cache get: name=" << name
<< " : type miss (requested=0x"
53 << std::hex
<< mask
<< ", cached=0x" << src
.flags
54 << std::dec
<< ")" << dendl
;
55 if(perfcounter
) perfcounter
->inc(l_rgw_cache_miss
);
58 ldout(cct
, 10) << "cache get: name=" << name
<< " : hit (requested=0x"
59 << std::hex
<< mask
<< ", cached=0x" << src
.flags
60 << std::dec
<< ")" << dendl
;
64 cache_info
->cache_locator
= name
;
65 cache_info
->gen
= entry
->gen
;
67 if(perfcounter
) perfcounter
->inc(l_rgw_cache_hit
);
72 bool ObjectCache::chain_cache_entry(list
<rgw_cache_entry_info
*>& cache_info_entries
, RGWChainedCache::Entry
*chained_entry
)
74 RWLock::WLocker
l(lock
);
80 list
<rgw_cache_entry_info
*>::iterator citer
;
82 list
<ObjectCacheEntry
*> cache_entry_list
;
84 /* first verify that all entries are still valid */
85 for (citer
= cache_info_entries
.begin(); citer
!= cache_info_entries
.end(); ++citer
) {
86 rgw_cache_entry_info
*cache_info
= *citer
;
88 ldout(cct
, 10) << "chain_cache_entry: cache_locator=" << cache_info
->cache_locator
<< dendl
;
89 map
<string
, ObjectCacheEntry
>::iterator iter
= cache_map
.find(cache_info
->cache_locator
);
90 if (iter
== cache_map
.end()) {
91 ldout(cct
, 20) << "chain_cache_entry: couldn't find cache locator" << dendl
;
95 ObjectCacheEntry
*entry
= &iter
->second
;
97 if (entry
->gen
!= cache_info
->gen
) {
98 ldout(cct
, 20) << "chain_cache_entry: entry.gen (" << entry
->gen
<< ") != cache_info.gen (" << cache_info
->gen
<< ")" << dendl
;
102 cache_entry_list
.push_back(entry
);
106 chained_entry
->cache
->chain_cb(chained_entry
->key
, chained_entry
->data
);
108 list
<ObjectCacheEntry
*>::iterator liter
;
110 for (liter
= cache_entry_list
.begin(); liter
!= cache_entry_list
.end(); ++liter
) {
111 ObjectCacheEntry
*entry
= *liter
;
113 entry
->chained_entries
.push_back(make_pair(chained_entry
->cache
, chained_entry
->key
));
119 void ObjectCache::put(string
& name
, ObjectCacheInfo
& info
, rgw_cache_entry_info
*cache_info
)
121 RWLock::WLocker
l(lock
);
127 ldout(cct
, 10) << "cache put: name=" << name
<< " info.flags=0x"
128 << std::hex
<< info
.flags
<< std::dec
<< dendl
;
129 map
<string
, ObjectCacheEntry
>::iterator iter
= cache_map
.find(name
);
130 if (iter
== cache_map
.end()) {
131 ObjectCacheEntry entry
;
132 entry
.lru_iter
= lru
.end();
133 cache_map
.insert(pair
<string
, ObjectCacheEntry
>(name
, entry
));
134 iter
= cache_map
.find(name
);
136 ObjectCacheEntry
& entry
= iter
->second
;
137 ObjectCacheInfo
& target
= entry
.info
;
139 for (list
<pair
<RGWChainedCache
*, string
> >::iterator iiter
= entry
.chained_entries
.begin();
140 iiter
!= entry
.chained_entries
.end(); ++iiter
) {
141 RGWChainedCache
*chained_cache
= iiter
->first
;
142 chained_cache
->invalidate(iiter
->second
);
145 entry
.chained_entries
.clear();
148 touch_lru(name
, entry
, entry
.lru_iter
);
150 target
.status
= info
.status
;
152 if (info
.status
< 0) {
154 target
.xattrs
.clear();
160 cache_info
->cache_locator
= name
;
161 cache_info
->gen
= entry
.gen
;
164 target
.flags
|= info
.flags
;
166 if (info
.flags
& CACHE_FLAG_META
)
167 target
.meta
= info
.meta
;
168 else if (!(info
.flags
& CACHE_FLAG_MODIFY_XATTRS
))
169 target
.flags
&= ~CACHE_FLAG_META
; // non-meta change should reset meta
171 if (info
.flags
& CACHE_FLAG_XATTRS
) {
172 target
.xattrs
= info
.xattrs
;
173 map
<string
, bufferlist
>::iterator iter
;
174 for (iter
= target
.xattrs
.begin(); iter
!= target
.xattrs
.end(); ++iter
) {
175 ldout(cct
, 10) << "updating xattr: name=" << iter
->first
<< " bl.length()=" << iter
->second
.length() << dendl
;
177 } else if (info
.flags
& CACHE_FLAG_MODIFY_XATTRS
) {
178 map
<string
, bufferlist
>::iterator iter
;
179 for (iter
= info
.rm_xattrs
.begin(); iter
!= info
.rm_xattrs
.end(); ++iter
) {
180 ldout(cct
, 10) << "removing xattr: name=" << iter
->first
<< dendl
;
181 target
.xattrs
.erase(iter
->first
);
183 for (iter
= info
.xattrs
.begin(); iter
!= info
.xattrs
.end(); ++iter
) {
184 ldout(cct
, 10) << "appending xattr: name=" << iter
->first
<< " bl.length()=" << iter
->second
.length() << dendl
;
185 target
.xattrs
[iter
->first
] = iter
->second
;
189 if (info
.flags
& CACHE_FLAG_DATA
)
190 target
.data
= info
.data
;
192 if (info
.flags
& CACHE_FLAG_OBJV
)
193 target
.version
= info
.version
;
196 void ObjectCache::remove(string
& name
)
198 RWLock::WLocker
l(lock
);
204 map
<string
, ObjectCacheEntry
>::iterator iter
= cache_map
.find(name
);
205 if (iter
== cache_map
.end())
208 ldout(cct
, 10) << "removing " << name
<< " from cache" << dendl
;
209 ObjectCacheEntry
& entry
= iter
->second
;
211 for (list
<pair
<RGWChainedCache
*, string
> >::iterator iiter
= entry
.chained_entries
.begin();
212 iiter
!= entry
.chained_entries
.end(); ++iiter
) {
213 RGWChainedCache
*chained_cache
= iiter
->first
;
214 chained_cache
->invalidate(iiter
->second
);
217 remove_lru(name
, iter
->second
.lru_iter
);
218 cache_map
.erase(iter
);
221 void ObjectCache::touch_lru(string
& name
, ObjectCacheEntry
& entry
, std::list
<string
>::iterator
& lru_iter
)
223 while (lru_size
> (size_t)cct
->_conf
->rgw_cache_lru_size
) {
224 list
<string
>::iterator iter
= lru
.begin();
225 if ((*iter
).compare(name
) == 0) {
227 * if the entry we're touching happens to be at the lru end, don't remove it,
228 * lru shrinking can wait for next time
232 map
<string
, ObjectCacheEntry
>::iterator map_iter
= cache_map
.find(*iter
);
233 ldout(cct
, 10) << "removing entry: name=" << *iter
<< " from cache LRU" << dendl
;
234 if (map_iter
!= cache_map
.end())
235 cache_map
.erase(map_iter
);
240 if (lru_iter
== lru
.end()) {
244 ldout(cct
, 10) << "adding " << name
<< " to cache LRU end" << dendl
;
246 ldout(cct
, 10) << "moving " << name
<< " to cache LRU end" << dendl
;
249 lru_iter
= lru
.end();
254 entry
.lru_promotion_ts
= lru_counter
;
257 void ObjectCache::remove_lru(string
& name
, std::list
<string
>::iterator
& lru_iter
)
259 if (lru_iter
== lru
.end())
264 lru_iter
= lru
.end();
267 void ObjectCache::set_enabled(bool status
)
269 RWLock::WLocker
l(lock
);
278 void ObjectCache::invalidate_all()
280 RWLock::WLocker
l(lock
);
285 void ObjectCache::do_invalidate_all()
294 for (list
<RGWChainedCache
*>::iterator iter
= chained_cache
.begin(); iter
!= chained_cache
.end(); ++iter
) {
295 (*iter
)->invalidate_all();
299 void ObjectCache::chain_cache(RGWChainedCache
*cache
) {
300 RWLock::WLocker
l(lock
);
301 chained_cache
.push_back(cache
);