1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
8 #include <unordered_map>
9 #include "include/types.h"
10 #include "include/utime.h"
11 #include "include/ceph_assert.h"
12 #include "common/ceph_mutex.h"
14 #include "cls/version/cls_version_types.h"
15 #include "rgw_common.h"
22 #define CACHE_FLAG_DATA 0x01
23 #define CACHE_FLAG_XATTRS 0x02
24 #define CACHE_FLAG_META 0x04
25 #define CACHE_FLAG_MODIFY_XATTRS 0x08
26 #define CACHE_FLAG_OBJV 0x10
28 struct ObjectMetaInfo
{
32 ObjectMetaInfo() : size(0) {}
34 void encode(bufferlist
& bl
) const {
35 ENCODE_START(2, 2, bl
);
40 void decode(bufferlist::const_iterator
& bl
) {
41 DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, bl
);
46 void dump(Formatter
*f
) const;
47 static void generate_test_instances(std::list
<ObjectMetaInfo
*>& o
);
49 WRITE_CLASS_ENCODER(ObjectMetaInfo
)
51 struct ObjectCacheInfo
{
56 std::map
<std::string
, bufferlist
> xattrs
;
57 std::map
<std::string
, bufferlist
> rm_xattrs
;
59 obj_version version
= {};
60 ceph::coarse_mono_time time_added
;
62 ObjectCacheInfo() = default;
64 void encode(bufferlist
& bl
) const {
65 ENCODE_START(5, 3, bl
);
71 encode(rm_xattrs
, bl
);
76 void decode(bufferlist::const_iterator
& bl
) {
77 DECODE_START_LEGACY_COMPAT_LEN(5, 3, 3, bl
);
84 decode(rm_xattrs
, bl
);
91 void dump(Formatter
*f
) const;
92 static void generate_test_instances(std::list
<ObjectCacheInfo
*>& o
);
94 WRITE_CLASS_ENCODER(ObjectCacheInfo
)
96 struct RGWCacheNotifyInfo
{
99 ObjectCacheInfo obj_info
;
103 RGWCacheNotifyInfo() : op(0), ofs(0) {}
105 void encode(bufferlist
& obl
) const {
106 ENCODE_START(2, 2, obl
);
109 encode(obj_info
, obl
);
114 void decode(bufferlist::const_iterator
& ibl
) {
115 DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, ibl
);
118 decode(obj_info
, ibl
);
123 void dump(Formatter
*f
) const;
124 static void generate_test_instances(std::list
<RGWCacheNotifyInfo
*>& o
);
126 WRITE_CLASS_ENCODER(RGWCacheNotifyInfo
)
127 inline std::ostream
& operator <<(std::ostream
& m
, const RGWCacheNotifyInfo
& cni
) {
128 return m
<< "[op: " << cni
.op
<< ", obj: " << cni
.obj
129 << ", ofs" << cni
.ofs
<< ", ns" << cni
.ns
<< "]";
133 class RGWChainedCache
{
135 virtual ~RGWChainedCache() {}
136 virtual void chain_cb(const std::string
& key
, void *data
) = 0;
137 virtual void invalidate(const std::string
& key
) = 0;
138 virtual void invalidate_all() = 0;
139 virtual void unregistered() {}
142 RGWChainedCache
*cache
;
143 const std::string
& key
;
146 Entry(RGWChainedCache
*_c
, const std::string
& _k
, void *_d
) : cache(_c
), key(_k
), data(_d
) {}
151 struct ObjectCacheEntry
{
152 ObjectCacheInfo info
;
153 std::list
<std::string
>::iterator lru_iter
;
154 uint64_t lru_promotion_ts
;
156 std::vector
<std::pair
<RGWChainedCache
*, std::string
> > chained_entries
;
158 ObjectCacheEntry() : lru_promotion_ts(0), gen(0) {}
162 std::unordered_map
<std::string
, ObjectCacheEntry
> cache_map
;
163 std::list
<std::string
> lru
;
164 unsigned long lru_size
;
165 unsigned long lru_counter
;
166 unsigned long lru_window
;
167 ceph::shared_mutex lock
= ceph::make_shared_mutex("ObjectCache");
170 std::vector
<RGWChainedCache
*> chained_cache
;
173 ceph::timespan expiry
;
175 void touch_lru(const DoutPrefixProvider
*dpp
, const std::string
& name
, ObjectCacheEntry
& entry
,
176 std::list
<std::string
>::iterator
& lru_iter
);
177 void remove_lru(const std::string
& name
, std::list
<std::string
>::iterator
& lru_iter
);
178 void invalidate_lru(ObjectCacheEntry
& entry
);
180 void do_invalidate_all();
183 ObjectCache() : lru_size(0), lru_counter(0), lru_window(0), cct(NULL
), enabled(false) { }
185 int get(const DoutPrefixProvider
*dpp
, const std::string
& name
, ObjectCacheInfo
& bl
, uint32_t mask
, rgw_cache_entry_info
*cache_info
);
186 std::optional
<ObjectCacheInfo
> get(const DoutPrefixProvider
*dpp
, const std::string
& name
) {
187 std::optional
<ObjectCacheInfo
> info
{std::in_place
};
188 auto r
= get(dpp
, name
, *info
, 0, nullptr);
189 return r
< 0 ? std::nullopt
: info
;
193 void for_each(const F
& f
) {
194 std::shared_lock l
{lock
};
196 auto now
= ceph::coarse_mono_clock::now();
197 for (const auto& [name
, entry
] : cache_map
) {
198 if (expiry
.count() && (now
- entry
.info
.time_added
) < expiry
) {
205 void put(const DoutPrefixProvider
*dpp
, const std::string
& name
, ObjectCacheInfo
& bl
, rgw_cache_entry_info
*cache_info
);
206 bool invalidate_remove(const DoutPrefixProvider
*dpp
, const std::string
& name
);
207 void set_ctx(CephContext
*_cct
) {
209 lru_window
= cct
->_conf
->rgw_cache_lru_size
/ 2;
210 expiry
= std::chrono::seconds(cct
->_conf
.get_val
<uint64_t>(
211 "rgw_cache_expiry_interval"));
213 bool chain_cache_entry(const DoutPrefixProvider
*dpp
,
214 std::initializer_list
<rgw_cache_entry_info
*> cache_info_entries
,
215 RGWChainedCache::Entry
*chained_entry
);
217 void set_enabled(bool status
);
219 void chain_cache(RGWChainedCache
*cache
);
220 void unchain_cache(RGWChainedCache
*cache
);
221 void invalidate_all();