]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_cache.h
659b5518128e8d5c1ca2a80ee78457be88a78958
[ceph.git] / ceph / src / rgw / rgw_cache.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
3
4 #ifndef CEPH_RGWCACHE_H
5 #define CEPH_RGWCACHE_H
6
7 #include <string>
8 #include <map>
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"
14
15 #include "cls/version/cls_version_types.h"
16 #include "rgw_common.h"
17
18 enum {
19 UPDATE_OBJ,
20 REMOVE_OBJ,
21 };
22
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
28
29 struct ObjectMetaInfo {
30 uint64_t size;
31 real_time mtime;
32
33 ObjectMetaInfo() : size(0) {}
34
35 void encode(bufferlist& bl) const {
36 ENCODE_START(2, 2, bl);
37 encode(size, bl);
38 encode(mtime, bl);
39 ENCODE_FINISH(bl);
40 }
41 void decode(bufferlist::const_iterator& bl) {
42 DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, bl);
43 decode(size, bl);
44 decode(mtime, bl);
45 DECODE_FINISH(bl);
46 }
47 void dump(Formatter *f) const;
48 static void generate_test_instances(list<ObjectMetaInfo*>& o);
49 };
50 WRITE_CLASS_ENCODER(ObjectMetaInfo)
51
52 struct ObjectCacheInfo {
53 int status = 0;
54 uint32_t flags = 0;
55 uint64_t epoch = 0;
56 bufferlist data;
57 map<string, bufferlist> xattrs;
58 map<string, bufferlist> rm_xattrs;
59 ObjectMetaInfo meta;
60 obj_version version = {};
61 ceph::coarse_mono_time time_added;
62
63 ObjectCacheInfo() = default;
64
65 void encode(bufferlist& bl) const {
66 ENCODE_START(5, 3, bl);
67 encode(status, bl);
68 encode(flags, bl);
69 encode(data, bl);
70 encode(xattrs, bl);
71 encode(meta, bl);
72 encode(rm_xattrs, bl);
73 encode(epoch, bl);
74 encode(version, bl);
75 ENCODE_FINISH(bl);
76 }
77 void decode(bufferlist::const_iterator& bl) {
78 DECODE_START_LEGACY_COMPAT_LEN(5, 3, 3, bl);
79 decode(status, bl);
80 decode(flags, bl);
81 decode(data, bl);
82 decode(xattrs, bl);
83 decode(meta, bl);
84 if (struct_v >= 2)
85 decode(rm_xattrs, bl);
86 if (struct_v >= 4)
87 decode(epoch, bl);
88 if (struct_v >= 5)
89 decode(version, bl);
90 DECODE_FINISH(bl);
91 }
92 void dump(Formatter *f) const;
93 static void generate_test_instances(list<ObjectCacheInfo*>& o);
94 };
95 WRITE_CLASS_ENCODER(ObjectCacheInfo)
96
97 struct RGWCacheNotifyInfo {
98 uint32_t op;
99 rgw_raw_obj obj;
100 ObjectCacheInfo obj_info;
101 off_t ofs;
102 string ns;
103
104 RGWCacheNotifyInfo() : op(0), ofs(0) {}
105
106 void encode(bufferlist& obl) const {
107 ENCODE_START(2, 2, obl);
108 encode(op, obl);
109 encode(obj, obl);
110 encode(obj_info, obl);
111 encode(ofs, obl);
112 encode(ns, obl);
113 ENCODE_FINISH(obl);
114 }
115 void decode(bufferlist::const_iterator& ibl) {
116 DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, ibl);
117 decode(op, ibl);
118 decode(obj, ibl);
119 decode(obj_info, ibl);
120 decode(ofs, ibl);
121 decode(ns, ibl);
122 DECODE_FINISH(ibl);
123 }
124 void dump(Formatter *f) const;
125 static void generate_test_instances(list<RGWCacheNotifyInfo*>& o);
126 };
127 WRITE_CLASS_ENCODER(RGWCacheNotifyInfo)
128
129 class RGWChainedCache {
130 public:
131 virtual ~RGWChainedCache() {}
132 virtual void chain_cb(const string& key, void *data) = 0;
133 virtual void invalidate(const string& key) = 0;
134 virtual void invalidate_all() = 0;
135 virtual void unregistered() {}
136
137 struct Entry {
138 RGWChainedCache *cache;
139 const string& key;
140 void *data;
141
142 Entry(RGWChainedCache *_c, const string& _k, void *_d) : cache(_c), key(_k), data(_d) {}
143 };
144 };
145
146
147 struct ObjectCacheEntry {
148 ObjectCacheInfo info;
149 std::list<string>::iterator lru_iter;
150 uint64_t lru_promotion_ts;
151 uint64_t gen;
152 std::vector<pair<RGWChainedCache *, string> > chained_entries;
153
154 ObjectCacheEntry() : lru_promotion_ts(0), gen(0) {}
155 };
156
157 class ObjectCache {
158 std::unordered_map<string, ObjectCacheEntry> cache_map;
159 std::list<string> lru;
160 unsigned long lru_size;
161 unsigned long lru_counter;
162 unsigned long lru_window;
163 ceph::shared_mutex lock = ceph::make_shared_mutex("ObjectCache");
164 CephContext *cct;
165
166 vector<RGWChainedCache *> chained_cache;
167
168 bool enabled;
169 ceph::timespan expiry;
170
171 void touch_lru(const string& name, ObjectCacheEntry& entry,
172 std::list<string>::iterator& lru_iter);
173 void remove_lru(const string& name, std::list<string>::iterator& lru_iter);
174 void invalidate_lru(ObjectCacheEntry& entry);
175
176 void do_invalidate_all();
177
178 public:
179 ObjectCache() : lru_size(0), lru_counter(0), lru_window(0), cct(NULL), enabled(false) { }
180 ~ObjectCache();
181 int get(const std::string& name, ObjectCacheInfo& bl, uint32_t mask, rgw_cache_entry_info *cache_info);
182 std::optional<ObjectCacheInfo> get(const std::string& name) {
183 std::optional<ObjectCacheInfo> info{std::in_place};
184 auto r = get(name, *info, 0, nullptr);
185 return r < 0 ? std::nullopt : info;
186 }
187
188 template<typename F>
189 void for_each(const F& f) {
190 std::shared_lock l{lock};
191 if (enabled) {
192 auto now = ceph::coarse_mono_clock::now();
193 for (const auto& [name, entry] : cache_map) {
194 if (expiry.count() && (now - entry.info.time_added) < expiry) {
195 f(name, entry);
196 }
197 }
198 }
199 }
200
201 void put(const std::string& name, ObjectCacheInfo& bl, rgw_cache_entry_info *cache_info);
202 bool remove(const std::string& name);
203 void set_ctx(CephContext *_cct) {
204 cct = _cct;
205 lru_window = cct->_conf->rgw_cache_lru_size / 2;
206 expiry = std::chrono::seconds(cct->_conf.get_val<uint64_t>(
207 "rgw_cache_expiry_interval"));
208 }
209 bool chain_cache_entry(std::initializer_list<rgw_cache_entry_info*> cache_info_entries,
210 RGWChainedCache::Entry *chained_entry);
211
212 void set_enabled(bool status);
213
214 void chain_cache(RGWChainedCache *cache);
215 void unchain_cache(RGWChainedCache *cache);
216 void invalidate_all();
217 };
218
219 #endif