aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSaturneric <[email protected]>2023-07-13 06:49:36 +0000
committerSaturneric <[email protected]>2023-07-13 06:49:36 +0000
commitb6048613d4b62f2af911b411f23aef0fbe5a88f8 (patch)
tree8838cf23fc247acda5ab6049fbc85a3ea76f92bd
parentfix: recommand not require (diff)
downloadGpgFrontend-b6048613d4b62f2af911b411f23aef0fbe5a88f8.tar.gz
GpgFrontend-b6048613d4b62f2af911b411f23aef0fbe5a88f8.zip
feat: add CacheManager to deal with cache
-rw-r--r--src/core/function/CacheManager.cpp111
-rw-r--r--src/core/function/CacheManager.h75
-rw-r--r--src/core/function/DataObjectOperator.h1
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"