diff options
author | Saturneric <[email protected]> | 2023-07-13 06:49:36 +0000 |
---|---|---|
committer | Saturneric <[email protected]> | 2023-07-13 06:49:36 +0000 |
commit | b6048613d4b62f2af911b411f23aef0fbe5a88f8 (patch) | |
tree | 8838cf23fc247acda5ab6049fbc85a3ea76f92bd | |
parent | fix: recommand not require (diff) | |
download | GpgFrontend-b6048613d4b62f2af911b411f23aef0fbe5a88f8.tar.gz GpgFrontend-b6048613d4b62f2af911b411f23aef0fbe5a88f8.zip |
feat: add CacheManager to deal with cache
-rw-r--r-- | src/core/function/CacheManager.cpp | 111 | ||||
-rw-r--r-- | src/core/function/CacheManager.h | 75 | ||||
-rw-r--r-- | src/core/function/DataObjectOperator.h | 1 |
3 files changed, 165 insertions, 22 deletions
diff --git a/src/core/function/CacheManager.cpp b/src/core/function/CacheManager.cpp index a20b8003..c5270999 100644 --- a/src/core/function/CacheManager.cpp +++ b/src/core/function/CacheManager.cpp @@ -29,38 +29,115 @@ #include "CacheManager.h" #include <algorithm> +#include <boost/format.hpp> +#include <string> #include "function/DataObjectOperator.h" -#include "nlohmann/json_fwd.hpp" #include "spdlog/spdlog.h" +GpgFrontend::CacheManager::CacheManager(int channel) + : m_timer_(new QTimer(this)), + SingletonFunctionObject<CacheManager>(channel) { + connect(m_timer_, &QTimer::timeout, this, &CacheManager::flush_cache_storage); + m_timer_->start(15000); + + load_all_cache_storage(); +} + void GpgFrontend::CacheManager::SaveCache(std::string key, - const nlohmann::json &value) { + const nlohmann::json& value) { + auto data_object_key = get_data_object_key(key); + cache_storage_.insert(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); + } +} + +nlohmann::json GpgFrontend::CacheManager::LoadCache(std::string key) { + auto data_object_key = get_data_object_key(key); + + SPDLOG_DEBUG("load cache, data object key: {}", data_object_key); + if (!cache_storage_.exists(key)) { + cache_storage_.insert(key, load_cache_storage(key, {})); + } + + auto cache = cache_storage_.get(key); + if (cache) + return *cache; + else + return {}; +} + +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)); + } + + auto cache = cache_storage_.get(key); + if (cache) + return *cache; + else + return {}; +} + +std::string GpgFrontend::CacheManager::get_data_object_key(std::string key) { + return (boost::format("__cache_data_%1%") % key).str(); +} + +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( - "__cache_data_list"); + data_object_key); - // get cache data list from file system - nlohmann::json cache_data_list; if (stored_data.has_value()) { - cache_data_list = std::move(stored_data.value()); + return stored_data.value(); + } else { + return default_value; + } +} + +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); } + GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(drk_key_, + key_storage_); +} + +void GpgFrontend::CacheManager::register_cache_key(std::string 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_); - if (!cache_data_list.is_array()) { - cache_data_list.clear(); + // 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 (GpgFrontend::DataObjectOperator::GetInstance() - .SaveDataObj(key, value) - .empty()) { + 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; } - if (std::find(cache_data_list.begin(), cache_data_list.end(), key) == - cache_data_list.end()) { - cache_data_list.push_back(key); + for (auto key : registered_key_list) { + load_cache_storage(key, {}); } - GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj( - "__cache_data_list", cache_data_list); -} + key_storage_ = registered_key_list; +}
\ No newline at end of file diff --git a/src/core/function/CacheManager.h b/src/core/function/CacheManager.h index e489182f..7a175586 100644 --- a/src/core/function/CacheManager.h +++ b/src/core/function/CacheManager.h @@ -29,15 +29,82 @@ #ifndef GPGFRONTEND_CACHEMANAGER_H #define GPGFRONTEND_CACHEMANAGER_H +#include <string> + +#include "core/GpgFunctionObject.h" + namespace GpgFrontend { -class CacheManager { +template <typename Key, typename Value> +class ThreadSafeMap { public: - static void SaveCache(std::string key, const nlohmann::json &value); + using MapType = std::map<Key, Value>; + using IteratorType = typename MapType::iterator; + + void insert(const Key& key, const Value& value) { + std::unique_lock lock(mutex_); + map_[key] = value; + } + + std::optional<Value> get(const Key& key) { + std::shared_lock lock(mutex_); + auto it = map_.find(key); + if (it != map_.end()) { + return it->second; + } + return std::nullopt; + } + + bool exists(const Key& key) { + std::shared_lock lock(mutex_); + return map_.count(key) > 0; + } + + IteratorType begin() { return map_mirror_.begin(); } + + IteratorType end() { return map_mirror_.end(); } + + ThreadSafeMap& mirror() { + std::shared_lock lock(mutex_); + map_mirror_ = map_; + return *this; + } + + private: + MapType map_mirror_; + MapType map_; + mutable std::shared_mutex mutex_; +}; + +class GPGFRONTEND_CORE_EXPORT CacheManager + : public QObject, + public SingletonFunctionObject<CacheManager> { + Q_OBJECT + public: + CacheManager(int channel = SingletonFunctionObject::GetDefaultChannel()); + + void SaveCache(std::string key, const nlohmann::json& value); + + nlohmann::json LoadCache(std::string key); + + nlohmann::json LoadCache(std::string key, nlohmann::json default_value); + + private: + std::string get_data_object_key(std::string key); + + nlohmann::json load_cache_storage(std::string key, + nlohmann::json default_value); + + void load_all_cache_storage(); + + void flush_cache_storage(); - static nlohmann::json LoadCache(std::string name); + void register_cache_key(std::string key); - static void ClearAllCache(); + 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"; }; } // namespace GpgFrontend diff --git a/src/core/function/DataObjectOperator.h b/src/core/function/DataObjectOperator.h index 97abc607..ae5dc62c 100644 --- a/src/core/function/DataObjectOperator.h +++ b/src/core/function/DataObjectOperator.h @@ -29,7 +29,6 @@ #ifndef GPGFRONTEND_DATAOBJECTOPERATOR_H #define GPGFRONTEND_DATAOBJECTOPERATOR_H -#include "core/GpgFrontendCore.h" #include "core/GpgFunctionObject.h" #include "core/function/GlobalSettingStation.h" |