aboutsummaryrefslogtreecommitdiffstats
path: root/src/core/function/CacheManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/function/CacheManager.cpp')
-rw-r--r--src/core/function/CacheManager.cpp286
1 files changed, 204 insertions, 82 deletions
diff --git a/src/core/function/CacheManager.cpp b/src/core/function/CacheManager.cpp
index 8445c648..161f9a0c 100644
--- a/src/core/function/CacheManager.cpp
+++ b/src/core/function/CacheManager.cpp
@@ -30,116 +30,238 @@
#include <algorithm>
#include <boost/format.hpp>
+#include <shared_mutex>
+#include <utility>
#include "function/DataObjectOperator.h"
-GpgFrontend::CacheManager::CacheManager(int channel)
- : SingletonFunctionObject<CacheManager>(channel),
- m_timer_(new QTimer(this)) {
- connect(m_timer_, &QTimer::timeout, this, &CacheManager::flush_cache_storage);
- m_timer_->start(15000);
+namespace GpgFrontend {
- load_all_cache_storage();
-}
+template <typename Key, typename Value>
+class ThreadSafeMap {
+ public:
+ using MapType = std::map<Key, Value>;
+ using IteratorType = typename MapType::iterator;
-void GpgFrontend::CacheManager::SaveCache(std::string key,
- const nlohmann::json& value,
- bool flush) {
- auto data_object_key = get_data_object_key(key);
- cache_storage_.insert(key, value);
+ void insert(const Key& key, const Value& value) {
+ std::unique_lock lock(mutex_);
+ map_[key] = value;
+ }
- if (std::find(key_storage_.begin(), key_storage_.end(), key) ==
- key_storage_.end()) {
- SPDLOG_DEBUG("register new key of cache", key);
- key_storage_.push_back(key);
+ auto get(const Key& key) -> std::optional<Value> {
+ std::shared_lock lock(mutex_);
+ auto it = map_.find(key);
+ if (it != map_.end()) {
+ return it->second;
+ }
+ return std::nullopt;
}
- if (flush) {
- flush_cache_storage();
+ auto exists(const Key& key) -> bool {
+ std::shared_lock lock(mutex_);
+ return map_.count(key) > 0;
}
-}
-nlohmann::json GpgFrontend::CacheManager::LoadCache(std::string key) {
- auto data_object_key = get_data_object_key(key);
+ auto begin() -> IteratorType { return map_mirror_.begin(); }
+
+ auto end() -> IteratorType { return map_mirror_.end(); }
- if (!cache_storage_.exists(key)) {
- cache_storage_.insert(key, load_cache_storage(key, {}));
+ auto mirror() -> ThreadSafeMap& {
+ std::shared_lock lock(mutex_);
+ map_mirror_ = map_;
+ return *this;
}
- auto cache = cache_storage_.get(key);
- if (cache)
- return *cache;
- else
- return {};
-}
+ auto remove(std::string key) -> bool {
+ std::unique_lock lock(mutex_);
+ auto it = map_.find(key);
+ if (it != map_.end()) {
+ map_.erase(it);
+ return true;
+ }
+ return false;
+ }
+
+ private:
+ MapType map_mirror_;
+ MapType map_;
+ mutable std::shared_mutex mutex_;
+};
-nlohmann::json GpgFrontend::CacheManager::LoadCache(
- std::string key, nlohmann::json default_value) {
- auto data_object_key = get_data_object_key(key);
- if (!cache_storage_.exists(key)) {
- cache_storage_.insert(key, load_cache_storage(key, default_value));
+class CacheManager::Impl : public SingletonFunctionObject<CacheManager::Impl> {
+ public:
+ Impl(CacheManager* parent, int channel)
+ : SingletonFunctionObject<CacheManager::Impl>(channel),
+ parent_(parent),
+ m_timer_(new QTimer(parent)) {
+ connect(m_timer_, &QTimer::timeout, parent_,
+ [this]() { flush_cache_storage(); });
+ m_timer_->start(15000);
+
+ load_all_cache_storage();
}
- auto cache = cache_storage_.get(key);
- if (cache)
- return *cache;
- else
- return {};
-}
+ void SaveCache(std::string key, const nlohmann::json& value, bool flush) {
+ auto data_object_key = get_data_object_key(key);
+ cache_storage_.insert(key, value);
-std::string GpgFrontend::CacheManager::get_data_object_key(std::string key) {
- return (boost::format("__cache_data_%1%") % key).str();
-}
+ if (std::find(key_storage_.begin(), key_storage_.end(), key) ==
+ key_storage_.end()) {
+ SPDLOG_DEBUG("register new key of cache", key);
+ key_storage_.push_back(key);
+ }
+
+ if (flush) {
+ flush_cache_storage();
+ }
+ }
-nlohmann::json GpgFrontend::CacheManager::load_cache_storage(
- std::string key, nlohmann::json default_value) {
- auto data_object_key = get_data_object_key(key);
- auto stored_data =
- GpgFrontend::DataObjectOperator::GetInstance().GetDataObject(
- data_object_key);
+ auto LoadCache(const std::string& key) -> nlohmann::json {
+ auto data_object_key = get_data_object_key(key);
- if (stored_data.has_value()) {
- return stored_data.value();
- } else {
- return default_value;
+ if (!cache_storage_.exists(key)) {
+ cache_storage_.insert(key, load_cache_storage(key, {}));
+ }
+
+ auto cache = cache_storage_.get(key);
+ if (cache) {
+ return *cache;
+ }
+ return {};
}
-}
-void GpgFrontend::CacheManager::flush_cache_storage() {
- for (auto cache : cache_storage_.mirror()) {
- auto key = get_data_object_key(cache.first);
- SPDLOG_DEBUG("save cache into filesystem, key {}, value size: {}", key,
- cache.second.size());
- GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(key,
- cache.second);
+ auto LoadCache(const std::string& key, nlohmann::json default_value)
+ -> nlohmann::json {
+ auto data_object_key = get_data_object_key(key);
+ if (!cache_storage_.exists(key)) {
+ cache_storage_.insert(key,
+ load_cache_storage(key, std::move(default_value)));
+ }
+
+ auto cache = cache_storage_.get(key);
+ if (cache) {
+ return *cache;
+ }
+ return {};
}
- GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(drk_key_,
- key_storage_);
-}
-void GpgFrontend::CacheManager::register_cache_key(std::string key) {}
+ auto ResetCache(const std::string& key) -> bool {
+ auto data_object_key = get_data_object_key(key);
+ return cache_storage_.remove(key);
+ }
-void GpgFrontend::CacheManager::load_all_cache_storage() {
- SPDLOG_DEBUG("start to load all cache from file system");
- auto stored_data =
- GpgFrontend::DataObjectOperator::GetInstance().GetDataObject(drk_key_);
+ private:
+ CacheManager* parent_;
+ ThreadSafeMap<std::string, nlohmann::json> cache_storage_;
+ nlohmann::json key_storage_;
+ QTimer* m_timer_;
+ const std::string drk_key_ = "__cache_manage_data_register_key_list";
- // get cache data list from file system
- nlohmann::json registered_key_list;
- if (stored_data.has_value()) {
- registered_key_list = std::move(stored_data.value());
+ /**
+ * @brief Get the data object key object
+ *
+ * @param key
+ * @return std::string
+ */
+ static auto get_data_object_key(std::string key) -> std::string {
+ return (boost::format("__cache_data_%1%") % key).str();
}
- if (!registered_key_list.is_array()) {
- GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(
- drk_key_, nlohmann::json::array());
- SPDLOG_ERROR("drk_key_ is not an array, abort.");
- return;
+ /**
+ * @brief
+ *
+ * @param key
+ * @param default_value
+ * @return nlohmann::json
+ */
+ static auto load_cache_storage(std::string key, nlohmann::json default_value)
+ -> nlohmann::json {
+ auto data_object_key = get_data_object_key(std::move(key));
+ auto stored_data =
+ GpgFrontend::DataObjectOperator::GetInstance().GetDataObject(
+ data_object_key);
+
+ if (stored_data.has_value()) {
+ return stored_data.value();
+ }
+ return default_value;
}
- for (auto key : registered_key_list) {
- load_cache_storage(key, {});
+ /**
+ * @brief
+ *
+ */
+ void load_all_cache_storage() {
+ SPDLOG_DEBUG("start to load all cache from file system");
+ auto stored_data =
+ GpgFrontend::DataObjectOperator::GetInstance().GetDataObject(drk_key_);
+
+ // get cache data list from file system
+ nlohmann::json registered_key_list;
+ if (stored_data.has_value()) {
+ registered_key_list = std::move(stored_data.value());
+ }
+
+ if (!registered_key_list.is_array()) {
+ GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(
+ drk_key_, nlohmann::json::array());
+ SPDLOG_ERROR("drk_key_ is not an array, abort.");
+ return;
+ }
+
+ for (const auto& key : registered_key_list) {
+ load_cache_storage(key, {});
+ }
+
+ key_storage_ = registered_key_list;
+ }
+
+ /**
+ * @brief
+ *
+ */
+ void flush_cache_storage() {
+ for (const auto& cache : cache_storage_.mirror()) {
+ auto key = get_data_object_key(cache.first);
+ SPDLOG_DEBUG("save cache into filesystem, key {}, value size: {}", key,
+ cache.second.size());
+ GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(key,
+ cache.second);
+ }
+ GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(drk_key_,
+ key_storage_);
}
- key_storage_ = registered_key_list;
-} \ No newline at end of file
+ /**
+ * @brief
+ *
+ * @param key
+ */
+ void register_cache_key(const std::string& key) {}
+};
+
+CacheManager::CacheManager(int channel)
+ : SingletonFunctionObject<CacheManager>(channel),
+ p_(std::make_unique<Impl>(this, channel)) {}
+
+CacheManager::~CacheManager() = default;
+
+void CacheManager::SaveCache(std::string key, const nlohmann::json& value,
+ bool flush) {
+ p_->SaveCache(std::move(key), value, flush);
+}
+
+auto CacheManager::LoadCache(std::string key) -> nlohmann::json {
+ return p_->LoadCache(key);
+}
+
+auto CacheManager::LoadCache(std::string key, nlohmann::json default_value)
+ -> nlohmann::json {
+ return p_->LoadCache(key, std::move(default_value));
+}
+
+auto CacheManager::ResetCache(std::string key) -> bool {
+ return p_->ResetCache(key);
+}
+
+} // namespace GpgFrontend