1 | #pragma once |
2 | |
3 | #include <map> |
4 | #include <tuple> |
5 | #include <mutex> |
6 | #include <ext/function_traits.h> |
7 | |
8 | |
9 | /** The simplest cache for a free function. |
10 | * You can also pass a static class method or lambda without captures. |
11 | * The size is unlimited. Values are stored permanently and never evicted. |
12 | * But single record or all cache can be manually dropped. |
13 | * Mutex is used for synchronization. |
14 | * Suitable only for the simplest cases. |
15 | * |
16 | * Usage |
17 | * |
18 | * SimpleCache<decltype(func), &func> func_cached; |
19 | * std::cerr << func_cached(args...); |
20 | */ |
21 | template <typename F, F* f> |
22 | class SimpleCache |
23 | { |
24 | private: |
25 | using Key = typename function_traits<F>::arguments_decay; |
26 | using Result = typename function_traits<F>::result; |
27 | |
28 | std::map<Key, Result> cache; |
29 | mutable std::mutex mutex; |
30 | |
31 | public: |
32 | template <typename... Args> |
33 | Result operator() (Args &&... args) |
34 | { |
35 | { |
36 | std::lock_guard lock(mutex); |
37 | |
38 | Key key{std::forward<Args>(args)...}; |
39 | auto it = cache.find(key); |
40 | |
41 | if (cache.end() != it) |
42 | return it->second; |
43 | } |
44 | |
45 | /// The calculations themselves are not done under mutex. |
46 | Result res = f(std::forward<Args>(args)...); |
47 | |
48 | { |
49 | std::lock_guard lock(mutex); |
50 | |
51 | cache.emplace(std::forward_as_tuple(args...), res); |
52 | } |
53 | |
54 | return res; |
55 | } |
56 | |
57 | template <typename... Args> |
58 | void update(Args &&... args) |
59 | { |
60 | Result res = f(std::forward<Args>(args)...); |
61 | { |
62 | std::lock_guard lock(mutex); |
63 | |
64 | Key key{std::forward<Args>(args)...}; |
65 | cache[key] = std::move(res); |
66 | } |
67 | } |
68 | |
69 | size_t size() const |
70 | { |
71 | std::lock_guard lock(mutex); |
72 | return cache.size(); |
73 | } |
74 | |
75 | void drop() |
76 | { |
77 | std::lock_guard lock(mutex); |
78 | cache.clear(); |
79 | } |
80 | }; |
81 | |