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