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