Kagome
Polkadot Runtime Engine in C++17
objects_cache.hpp
Go to the documentation of this file.
1 
6 #ifndef KAGOME_CONTAINERS_OBJECTS_CACHE_HPP
7 #define KAGOME_CONTAINERS_OBJECTS_CACHE_HPP
8 
9 #include <memory>
10 #include <mutex>
11 #include <type_traits>
12 #include <vector>
13 
14 namespace tools::containers {
15 
21  template <typename Type>
23  template <typename... __args>
24  Type *allocate(__args &&...args) {
25  return new (std::nothrow) Type(std::forward<__args>(args)...); // NOLINT
26  }
27  void deallocate(Type *obj) {
28  delete obj; // NOLINT
29  }
30  };
31 
38  template <typename T, typename Alloc = ObjsCacheDefAlloc<T>>
39  struct ObjectsCache {
40  static_assert(std::is_array_v<T> == false,
41  "Arrays are not allowed in ObjectsCache");
42 
43  using Type = T;
44  using ObjectPtr = std::shared_ptr<Type>;
45 
46  ObjectsCache &operator=(const ObjectsCache &) = delete;
47  ObjectsCache(const ObjectsCache &) = delete;
48 
49  ObjectsCache &operator=(ObjectsCache &&) = delete;
50  ObjectsCache(ObjectsCache &&) = delete;
51 
52  ObjectsCache() = default;
53  ObjectsCache(Alloc &alloc) : allocator_(alloc) {}
54 
58  virtual ~ObjectsCache() {
59  for (auto *s : cache_) {
60  allocator_.deallocate(s);
61  }
62  }
63 
69  return getRawPtr();
70  }
71 
75  void setCachedObject(Type *const ptr) {
76  setRawPtr(ptr);
77  }
78 
84  return ObjectPtr(getRawPtr(), [&](auto *obj) mutable { setRawPtr(obj); });
85  }
86 
87  private:
88  using ObjectsArray = std::vector<Type *>;
89 
90  Alloc allocator_;
91  std::mutex cache_blocker_;
93 
94  inline Type *getRawPtr() {
95  Type *ptr;
96  std::lock_guard guard(cache_blocker_);
97  if (!cache_.empty()) {
98  ptr = cache_.back();
99  cache_.pop_back();
100  } else {
101  ptr = allocator_.allocate();
102  }
103  return ptr;
104  }
105 
106  inline void setRawPtr(Type *const ptr) {
107  if (nullptr != ptr) {
108  std::lock_guard guard(cache_blocker_);
109  cache_.push_back(ptr);
110  }
111  }
112  };
113 
118  template <typename T>
119  struct CacheUnit {
120  using Type =
121  typename std::remove_pointer<typename std::decay<T>::type>::type;
122  };
123 
129  template <typename T, typename... ARGS>
130  struct ObjectsCacheManager : public ObjectsCache<typename T::Type>,
131  public ObjectsCacheManager<ARGS...> {};
132 
133  template <typename T>
134  struct ObjectsCacheManager<T> : public ObjectsCache<typename T::Type> {};
135 
136 #ifndef KAGOME_CACHE_UNIT
137 #define KAGOME_CACHE_UNIT(type) tools::containers::CacheUnit<type>
138 #endif // KAGOME_CACHE_UNIT
139 
144 #ifndef KAGOME_DECLARE_CACHE
145 #define KAGOME_DECLARE_CACHE(prefix, ...) \
146  using prefix##_cache_type = \
147  tools::containers::ObjectsCacheManager<__VA_ARGS__>; \
148  template <typename T> \
149  using prefix##_UCachedType = std::unique_ptr<T, void (*)(T *const)>; \
150  extern prefix##_cache_type prefix##_cache; \
151  template <typename T> \
152  inline T *prefix##_get_from_cache() { \
153  return static_cast<tools::containers::ObjectsCache<T> *>(&prefix##_cache) \
154  ->getCachedObject(); \
155  } \
156  template <typename T> \
157  inline void prefix##_set_to_cache(T *const ptr) { \
158  static_cast<tools::containers::ObjectsCache<T> *>(&prefix##_cache) \
159  ->setCachedObject(ptr); \
160  } \
161  template <typename T> \
162  inline std::shared_ptr<T> prefix##_get_shared_from_cache() { \
163  return static_cast<tools::containers::ObjectsCache<T> *>(&prefix##_cache) \
164  ->getSharedCachedObject(); \
165  } \
166  template <typename T> \
167  inline prefix##_UCachedType<T> prefix##_get_unique_from_cache() { \
168  return prefix##_UCachedType<T>(prefix##_get_from_cache<T>(), \
169  &prefix##_set_to_cache<T>); \
170  }
171 #endif // KAGOME_DECLARE_CACHE
172 
173 #ifndef KAGOME_UNIQUE_TYPE_CACHE
174 #define KAGOME_UNIQUE_TYPE_CACHE(prefix, type) prefix##_UCachedType<type>
175 #endif // KAGOME_UNIQUE_TYPE_CACHE
176 
177 #ifndef KAGOME_DEFINE_CACHE
178 #define KAGOME_DEFINE_CACHE(prefix) prefix##_cache_type prefix##_cache;
179 #endif // KAGOME_DEFINE_CACHE
180 
181 #ifndef KAGOME_EXTRACT_SHARED_CACHE
182 #define KAGOME_EXTRACT_SHARED_CACHE(prefix, type) \
183  prefix##_get_shared_from_cache<type>()
184 #endif // KAGOME_EXTRACT_SHARED_CACHE
185 
186 #ifndef KAGOME_EXTRACT_UNIQUE_CACHE
187 #define KAGOME_EXTRACT_UNIQUE_CACHE(prefix, type) \
188  prefix##_get_unique_from_cache<type>()
189 #endif // KAGOME_EXTRACT_UNIQUE_CACHE
190 
191 #ifndef KAGOME_EXTRACT_RAW_CACHE
192 #define KAGOME_EXTRACT_RAW_CACHE(prefix, type) prefix##_get_from_cache<type>()
193 #endif // KAGOME_EXTRACT_RAW_CACHE
194 
195 #ifndef KAGOME_INSERT_RAW_CACHE
196 #define KAGOME_INSERT_RAW_CACHE(prefix, obj) prefix##_set_to_cache(obj)
197 #endif // KAGOME_INSERT_RAW_CACHE
198 
199 } // namespace tools::containers
200 
201 #endif // KAGOME_CONTAINERS_OBJECTS_CACHE_HPP
void setRawPtr(Type *const ptr)
typename std::remove_pointer< typename std::decay< T >::type >::type Type
void setCachedObject(Type *const ptr)
Type * allocate(__args &&...args)