Kagome
Polkadot Runtime Engine in C++17
runtime_instances_pool.hpp
Go to the documentation of this file.
1 
6 #ifndef KAGOME_CORE_RUNTIME_INSTANCES_POOL_HPP
7 #define KAGOME_CORE_RUNTIME_INSTANCES_POOL_HPP
8 
10 
11 #include <stack>
12 
13 namespace kagome::runtime {
17  template <typename Key, typename Value, typename PriorityType = uint64_t>
18  struct SmallLruCache final {
19  public:
20  static_assert(std::is_unsigned_v<PriorityType>);
21 
22  struct CacheEntry {
23  Key key;
24  Value value;
25  PriorityType latest_use_tick_;
26 
27  bool operator<(const CacheEntry &rhs) const {
28  return latest_use_tick_ < rhs.latest_use_tick_;
29  }
30  };
31 
32  SmallLruCache(size_t max_size) : kMaxSize{max_size} {
33  BOOST_ASSERT(kMaxSize > 0);
34  cache_.reserve(kMaxSize);
35  }
36 
37  std::optional<std::reference_wrapper<const Value>> get(const Key &key) {
38  ticks_++;
39  if (ticks_ == 0) {
41  }
42  for (auto &entry : cache_) {
43  if (entry.key == key) {
44  entry.latest_use_tick_ = ticks_;
45  return entry.value;
46  }
47  }
48  return std::nullopt;
49  }
50 
51  template <typename ValueArg>
52  void put(const Key &key, ValueArg &&value) {
53  static_assert(std::is_convertible_v<
54  ValueArg,
55  Value> || std::is_constructible_v<ValueArg, Value>);
56  ticks_++;
57  if (cache_.size() >= kMaxSize) {
58  auto min = std::min_element(cache_.begin(), cache_.end());
59  cache_.erase(min);
60  }
61  cache_.push_back(CacheEntry{key, std::forward<ValueArg>(value), ticks_});
62  }
63 
64  private:
66  // 'compress' timestamps of entries in the cache (works because we care
67  // only about their order, not actual timestamps)
68  std::sort(cache_.begin(), cache_.end());
69  for (auto &entry : cache_) {
70  entry.latest_use_tick_ = ticks_;
71  ticks_++;
72  }
73  }
74 
75  const size_t kMaxSize;
76  // an abstract representation of time to implement 'recency' without
77  // depending on real time. Incremented on each cache access
78  PriorityType ticks_{};
79  std::vector<CacheEntry> cache_;
80  };
81 
87  : public std::enable_shared_from_this<RuntimeInstancesPool> {
88  using ModuleInstancePool = std::stack<std::shared_ptr<ModuleInstance>>;
89 
90  public:
92  using ModuleCache =
94 
104  outcome::result<std::shared_ptr<ModuleInstance>> tryAcquire(
105  const RootHash &state);
113  void release(const RootHash &state,
114  std::shared_ptr<ModuleInstance> &&instance);
115 
122  std::optional<std::shared_ptr<Module>> getModule(const RootHash &state);
123 
130  void putModule(const RootHash &state, std::shared_ptr<Module> module);
131 
132  private:
133  std::mutex mt_;
134  static constexpr size_t MODULES_CACHE_SIZE = 2;
135  ModuleCache modules_{MODULES_CACHE_SIZE};
136  std::map<RootHash, ModuleInstancePool> pools_;
137  };
138 
139 } // namespace kagome::runtime
140 
141 #endif // KAGOME_CORE_RUNTIME_INSTANCES_POOL_HPP
void put(const Key &key, ValueArg &&value)
bool operator<(const CacheEntry &rhs) const
Key key
std::stack< std::shared_ptr< ModuleInstance >> ModuleInstancePool
PriorityType latest_use_tick_
string release
Definition: conf.py:18
Pool of runtime instances - per state. Incapsulates modules cache.
std::map< RootHash, ModuleInstancePool > pools_
Value value
common::Hash256 RootHash
Definition: types.hpp:13