1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
4 #ifndef CEPH_RGWCACHE_H
5 #define CEPH_RGWCACHE_H
9 #include <unordered_map>
10 #include "include/types.h"
11 #include "include/utime.h"
12 #include "include/ceph_assert.h"
13 #include "common/ceph_mutex.h"
15 #include "cls/version/cls_version_types.h"
16 #include "rgw_common.h"
23 #define CACHE_FLAG_DATA 0x01
24 #define CACHE_FLAG_XATTRS 0x02
25 #define CACHE_FLAG_META 0x04
26 #define CACHE_FLAG_MODIFY_XATTRS 0x08
27 #define CACHE_FLAG_OBJV 0x10
29 struct ObjectMetaInfo
{
33 ObjectMetaInfo() : size(0) {}
35 void encode(bufferlist
& bl
) const {
36 ENCODE_START(2, 2, bl
);
41 void decode(bufferlist::const_iterator
& bl
) {
42 DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, bl
);
47 void dump(Formatter
*f
) const;
48 static void generate_test_instances(std::list
<ObjectMetaInfo
*>& o
);
50 WRITE_CLASS_ENCODER(ObjectMetaInfo
)
52 struct ObjectCacheInfo
{
57 std::map
<std::string
, bufferlist
> xattrs
;
58 std::map
<std::string
, bufferlist
> rm_xattrs
;
60 obj_version version
= {};
61 ceph::coarse_mono_time time_added
;
63 ObjectCacheInfo() = default;
65 void encode(bufferlist
& bl
) const {
66 ENCODE_START(5, 3, bl
);
72 encode(rm_xattrs
, bl
);
77 void decode(bufferlist::const_iterator
& bl
) {
78 DECODE_START_LEGACY_COMPAT_LEN(5, 3, 3, bl
);
85 decode(rm_xattrs
, bl
);
92 void dump(Formatter
*f
) const;
93 static void generate_test_instances(std::list
<ObjectCacheInfo
*>& o
);
95 WRITE_CLASS_ENCODER(ObjectCacheInfo
)
97 struct RGWCacheNotifyInfo
{
100 ObjectCacheInfo obj_info
;
104 RGWCacheNotifyInfo() : op(0), ofs(0) {}
106 void encode(bufferlist
& obl
) const {
107 ENCODE_START(2, 2, obl
);
110 encode(obj_info
, obl
);
115 void decode(bufferlist::const_iterator
& ibl
) {
116 DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, ibl
);
119 decode(obj_info
, ibl
);
124 void dump(Formatter
*f
) const;
125 static void generate_test_instances(std::list
<RGWCacheNotifyInfo
*>& o
);
127 WRITE_CLASS_ENCODER(RGWCacheNotifyInfo
)
128 inline std::ostream
& operator <<(std::ostream
& m
, const RGWCacheNotifyInfo
& cni
) {
129 return m
<< "[op: " << cni
.op
<< ", obj: " << cni
.obj
130 << ", ofs" << cni
.ofs
<< ", ns" << cni
.ns
<< "]";
134 class RGWChainedCache
{
136 virtual ~RGWChainedCache() {}
137 virtual void chain_cb(const std::string
& key
, void *data
) = 0;
138 virtual void invalidate(const std::string
& key
) = 0;
139 virtual void invalidate_all() = 0;
140 virtual void unregistered() {}
143 RGWChainedCache
*cache
;
144 const std::string
& key
;
147 Entry(RGWChainedCache
*_c
, const std::string
& _k
, void *_d
) : cache(_c
), key(_k
), data(_d
) {}
152 struct ObjectCacheEntry
{
153 ObjectCacheInfo info
;
154 std::list
<std::string
>::iterator lru_iter
;
155 uint64_t lru_promotion_ts
;
157 std::vector
<std::pair
<RGWChainedCache
*, std::string
> > chained_entries
;
159 ObjectCacheEntry() : lru_promotion_ts(0), gen(0) {}
163 std::unordered_map
<std::string
, ObjectCacheEntry
> cache_map
;
164 std::list
<std::string
> lru
;
165 unsigned long lru_size
;
166 unsigned long lru_counter
;
167 unsigned long lru_window
;
168 ceph::shared_mutex lock
= ceph::make_shared_mutex("ObjectCache");
171 std::vector
<RGWChainedCache
*> chained_cache
;
174 ceph::timespan expiry
;
176 void touch_lru(const DoutPrefixProvider
*dpp
, const std::string
& name
, ObjectCacheEntry
& entry
,
177 std::list
<std::string
>::iterator
& lru_iter
);
178 void remove_lru(const std::string
& name
, std::list
<std::string
>::iterator
& lru_iter
);
179 void invalidate_lru(ObjectCacheEntry
& entry
);
181 void do_invalidate_all();
184 ObjectCache() : lru_size(0), lru_counter(0), lru_window(0), cct(NULL
), enabled(false) { }
186 int get(const DoutPrefixProvider
*dpp
, const std::string
& name
, ObjectCacheInfo
& bl
, uint32_t mask
, rgw_cache_entry_info
*cache_info
);
187 std::optional
<ObjectCacheInfo
> get(const DoutPrefixProvider
*dpp
, const std::string
& name
) {
188 std::optional
<ObjectCacheInfo
> info
{std::in_place
};
189 auto r
= get(dpp
, name
, *info
, 0, nullptr);
190 return r
< 0 ? std::nullopt
: info
;
194 void for_each(const F
& f
) {
195 std::shared_lock l
{lock
};
197 auto now
= ceph::coarse_mono_clock::now();
198 for (const auto& [name
, entry
] : cache_map
) {
199 if (expiry
.count() && (now
- entry
.info
.time_added
) < expiry
) {
206 void put(const DoutPrefixProvider
*dpp
, const std::string
& name
, ObjectCacheInfo
& bl
, rgw_cache_entry_info
*cache_info
);
207 bool invalidate_remove(const DoutPrefixProvider
*dpp
, const std::string
& name
);
208 void set_ctx(CephContext
*_cct
) {
210 lru_window
= cct
->_conf
->rgw_cache_lru_size
/ 2;
211 expiry
= std::chrono::seconds(cct
->_conf
.get_val
<uint64_t>(
212 "rgw_cache_expiry_interval"));
214 bool chain_cache_entry(const DoutPrefixProvider
*dpp
,
215 std::initializer_list
<rgw_cache_entry_info
*> cache_info_entries
,
216 RGWChainedCache::Entry
*chained_entry
);
218 void set_enabled(bool status
);
220 void chain_cache(RGWChainedCache
*cache
);
221 void unchain_cache(RGWChainedCache
*cache
);
222 void invalidate_all();