8#include <userver/cache/expirable_lru_cache.hpp>
9#include <userver/cache/lru_cache_config.hpp>
10#include <userver/components/component_base.hpp>
11#include <userver/dump/dumper.hpp>
12#include <userver/dump/meta.hpp>
13#include <userver/dump/operations.hpp>
14#include <userver/dynamic_config/source.hpp>
15#include <userver/logging/log.hpp>
16#include <userver/testsuite/cache_control.hpp>
17#include <userver/utils/statistics/entry.hpp>
18#include <userver/yaml_config/schema.hpp>
20USERVER_NAMESPACE_BEGIN
26void RegisterOnStatisticsStorage(
28 const std::string& name,
32dynamic_config::Source FindDynamicConfigSource(
const components::ComponentContext& context);
34bool IsDumpSupportEnabled(
const components::ComponentConfig& config);
36yaml_config::Schema GetLruCacheComponentBaseSchema();
68template <
typename Key,
typename Value,
typename Hash = std::hash<Key>,
typename Equal = std::equal_to<Key>>
72 using Cache = ExpirableLruCache<Key, Value, Hash, Equal>;
73 using CacheWrapper = LruCacheWrapper<Key, Value, Hash, Equal>;
77 ~LruCacheComponent()
override;
79 CacheWrapper GetCache();
84 virtual Value DoGetByKey(
const Key& key) = 0;
86 std::shared_ptr<Cache> GetCacheRaw() {
return cache_; }
91 Value GetByKey(
const Key& key);
93 void OnConfigUpdate(
const dynamic_config::Snapshot& cfg);
95 void UpdateConfig(
const LruCacheConfig& config);
99 void GetAndWrite(
dump::
Writer& writer)
const override;
100 void ReadAndSet(
dump::
Reader& reader)
override;
102 const std::string name_;
103 const LruCacheConfigStatic static_config_;
104 const std::shared_ptr<Cache> cache_;
105 std::shared_ptr<
dump::Dumper> dumper_;
108template <
typename Key,
typename Value,
typename Hash,
typename Equal>
113 Equal>::LruCacheComponent(
const components::ComponentConfig& config,
const components::ComponentContext& context)
116 static_config_(config),
117 cache_(std::make_shared<Cache>(static_config_.ways, static_config_.GetWaySize()))
119 if (impl::IsDumpSupportEnabled(config)) {
121 cache_->SetDumper(dumper_);
125 cache_->SetMaxLifetime(static_config_.config.lifetime);
126 cache_->SetBackgroundUpdate(static_config_.config.background_update);
128 if (static_config_.use_dynamic_config) {
130 <<
"Dynamic LRU cache config is enabled, subscribing on "
131 "dynamic-config updates, cache="
134 impl::FindDynamicConfigSource(context).UpdateAndListen(
141 LOG_INFO() <<
"Dynamic LRU cache config is disabled, cache=" << name_;
144 impl::RegisterOnStatisticsStorage(context, name_, [
this](
utils::
statistics::Writer& writer) { writer = *cache_; });
149template <
typename Key,
typename Value,
typename Hash,
typename Equal>
156template <
typename Key,
typename Value,
typename Hash,
typename Equal>
162 return CacheWrapper(cache_, [
this](
const Key& key) {
return GetByKey(key); });
165template <
typename Key,
typename Value,
typename Hash,
typename Equal>
167 cache_->Invalidate();
170template <
typename Key,
typename Value,
typename Hash,
typename Equal>
172 return DoGetByKey(key);
175template <
typename Key,
typename Value,
typename Hash,
typename Equal>
176void LruCacheComponent<Key, Value, Hash, Equal>::OnConfigUpdate(
const dynamic_config::Snapshot& cfg) {
177 const auto config = GetLruConfig(cfg, name_);
179 LOG_DEBUG() <<
"Using dynamic config for LRU cache";
180 UpdateConfig(*config);
182 LOG_DEBUG() <<
"Using static config for LRU cache";
183 UpdateConfig(static_config_.config);
187template <
typename Key,
typename Value,
typename Hash,
typename Equal>
188void LruCacheComponent<Key, Value, Hash, Equal>::UpdateConfig(
const LruCacheConfig& config) {
189 cache_->SetWaySize(config.GetWaySize(static_config_.ways));
190 cache_->SetMaxLifetime(config.lifetime);
191 cache_->SetBackgroundUpdate(config.background_update);
194template <
typename Key,
typename Value,
typename Hash,
typename Equal>
196 return impl::GetLruCacheComponentBaseSchema();
199template <
typename Key,
typename Value,
typename Hash,
typename Equal>
201 if constexpr (kCacheIsDumpable) {
202 cache_->Write(writer);
204 dump::ThrowDumpUnimplemented(name_);
208template <
typename Key,
typename Value,
typename Hash,
typename Equal>
210 if constexpr (kCacheIsDumpable) {
211 cache_->Read(reader);
213 dump::ThrowDumpUnimplemented(name_);