]> git.proxmox.com Git - ceph.git/blob - ceph/src/mgr/TTLCache.h
import quincy beta 17.1.0
[ceph.git] / ceph / src / mgr / TTLCache.h
1 #pragma once
2
3 #include <atomic>
4 #include <chrono>
5 #include <functional>
6 #include <map>
7 #include <memory>
8 #include <string>
9 #include <vector>
10
11 #include "PyUtil.h"
12
13 using namespace std;
14
15 template <class Key, class Value> class Cache {
16 private:
17 std::atomic<uint64_t> hits, misses;
18
19 protected:
20 unsigned int capacity;
21 Cache(unsigned int size = UINT16_MAX) : hits{0}, misses{0}, capacity{size} {};
22 std::map<Key, Value> content;
23 std::vector<string> allowed_keys = {"osd_map", "pg_dump", "pg_stats"};
24
25 void mark_miss() {
26 misses++;
27 }
28
29 void mark_hit() {
30 hits++;
31 }
32
33 unsigned int get_misses() { return misses; }
34 unsigned int get_hits() { return hits; }
35 void throw_key_not_found(Key key) {
36 std::stringstream ss;
37 ss << "Key " << key << " couldn't be found\n";
38 throw std::out_of_range(ss.str());
39 }
40
41 public:
42 void insert(Key key, Value value) {
43 mark_miss();
44 if (content.size() < capacity) {
45 content.insert({key, value});
46 }
47 }
48 Value get(Key key, bool count_hit = true) {
49 if (count_hit) {
50 mark_hit();
51 }
52 return content[key];
53 }
54 void erase(Key key) { content.erase(content.find(key)); }
55 void clear() { content.clear(); }
56 bool exists(Key key) { return content.find(key) != content.end(); }
57 std::pair<uint64_t, uint64_t> get_hit_miss_ratio() {
58 return std::make_pair(hits.load(), misses.load());
59 }
60 bool is_cacheable(Key key) {
61 for (auto k : allowed_keys) {
62 if (key == k) return true;
63 }
64 return false;
65 }
66 int size() { return content.size(); }
67
68 ~Cache(){};
69 };
70
71 using ttl_time_point = std::chrono::time_point<std::chrono::steady_clock>;
72 template <class Key, class Value>
73 class TTLCacheBase : public Cache<Key, std::pair<Value, ttl_time_point>> {
74 private:
75 uint16_t ttl;
76 float ttl_spread_ratio;
77 using value_type = std::pair<Value, ttl_time_point>;
78 using cache = Cache<Key, value_type>;
79
80 protected:
81 Value get_value(Key key, bool count_hit = true);
82 ttl_time_point get_value_time_point(Key key);
83 bool exists(Key key);
84 bool expired(Key key);
85 void finish_get(Key key);
86 void finish_erase(Key key);
87 void throw_key_not_found(Key key);
88
89 public:
90 TTLCacheBase(uint16_t ttl_ = 0, uint16_t size = UINT16_MAX,
91 float spread = 0.25)
92 : Cache<Key, value_type>(size), ttl{ttl_}, ttl_spread_ratio{spread} {}
93 ~TTLCacheBase(){};
94 void insert(Key key, Value value);
95 Value get(Key key);
96 void erase(Key key);
97 void clear();
98 uint16_t get_ttl() { return ttl; };
99 void set_ttl(uint16_t ttl);
100 };
101
102 template <class Key, class Value>
103 class TTLCache : public TTLCacheBase<Key, Value> {
104 public:
105 TTLCache(uint16_t ttl_ = 0, uint16_t size = UINT16_MAX, float spread = 0.25)
106 : TTLCacheBase<Key, Value>(ttl_, size, spread) {}
107 ~TTLCache(){};
108 };
109
110 template <class Key>
111 class TTLCache<Key, PyObject*> : public TTLCacheBase<Key, PyObject*> {
112 public:
113 TTLCache(uint16_t ttl_ = 0, uint16_t size = UINT16_MAX, float spread = 0.25)
114 : TTLCacheBase<Key, PyObject*>(ttl_, size, spread) {}
115 ~TTLCache(){};
116 PyObject* get(Key key);
117 void erase(Key key);
118
119 private:
120 using ttl_base = TTLCacheBase<Key, PyObject*>;
121 };
122
123 #include "TTLCache.cc"
124