eis/TestProject/play_gruond/shm/RuleStatShm.h

287 lines
8.9 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @file RuleStatShm.h
* @brief 共享内存 map用于将后台规则数据提供给页面使用
* @author your name (you@domain.com)
* @version 0.1
* @date 2023-10-18
*
* Copyright: Baosight Co. Ltd.
* DO NOT COPY/USE WITHOUT PERMISSION
*
*/
#pragma once
#include <mutex>
#include "shm_header.h"
namespace RuleStatShm {
using namespace ShmHeader;
const static std::string dir_path = "/users/dsc/shm";
const static std::string shm_file = "MapRuleStat"; ///<映射文件名
const double data_size = 500; ///< 数据大小 MB
const size_t stat_size_min = 1000; ///<统计样本最小批处理量
const size_t stat_size_max = 10000; ///<统计样本最大储存量
static managed_mapped_file_t obj_mapped_file(
bipc::open_or_create, (dir_path + "/" + shm_file + "_boost.mmap").c_str(),
mix_cc::data_size::MB(data_size));
static void_allocator default_allocator(
obj_mapped_file.get_segment_manager()); ///<默认分配器
static char_string key_object("", default_allocator);
static char_string key_delete("", default_allocator);
///<定义数据
struct RuleStat {
/** 动态数据 规则触发更新 **/
double alarm_value = 0; ///<最新报警值
double current_value = 0; ///<当前值
double limit_up = 0; ///<上限
double limit_down = 0; ///<下限
vector_s items; ///<数据项
vector_d stat_values; ///<统计值用于cron
bool fetch_mark = false; ///<取数据标记
/** 静态数据 定时更新 **/
double running_time = 0; ///<累积的运行时间
int64_t shear_times = 0; ///<剪切次数
int64_t alarm_times = 0; ///<报警次数
bipc::string last_alarm_time = "无报警"; ///<上次报警时间
bipc::string dev_coder; ///<设备编码
RuleStat()
: items(default_allocator),
stat_values(default_allocator) {} ///<共享内存的内存分配
/** 数据操作 **/
mix_cc::json invert2json() {
mix_cc::json js1;
/** 动态数据 规则触发更新 **/
js1["alarm_value"] = alarm_value; ///<最新报警值
js1["current_value"] = current_value; ///<当前值
js1["limit_up"] = limit_up; ///<上限阈值
js1["limit_down"] = limit_down; ///<下限阈值
js1["items"] = items; ///< tag点
/** 静态数据 定时更新 **/
js1["running_time"] = running_time; ///<统计的运行时间
js1["shear_times"] = shear_times; ///<剪切次数
js1["alarm_times"] = alarm_times; ///<报警次数
js1["last_alarm_time"] = last_alarm_time; ///<上次报警时间
js1["dev_coder"] = dev_coder; ///<设备编码
return js1;
}
bool update_dynamic(const RuleStat& value) {
alarm_value = value.alarm_value;
current_value = value.current_value;
limit_up = value.limit_up;
limit_down = value.limit_down;
items = value.items;
}
bool update_static(const RuleStat& value) {
running_time = value.running_time;
shear_times = value.shear_times;
alarm_times = value.alarm_times;
last_alarm_time = value.last_alarm_time;
dev_coder = value.dev_coder;
}
};
///< key 是string的情况
typedef std::pair<const char_string, RuleStat> pair_s; ///< key-value
typedef bipc::node_allocator<pair_s, mapped_segment_manager_t>
allocator_s; ///<映射文件
typedef std::less<char_string> less_s;
typedef bipc::map<char_string, RuleStat, less_s, allocator_s> MapRuleStat_s;
typedef MapRuleStat_s::iterator map_iter_s;
///<定义数据操作
struct MapRuleStat {
private:
MapRuleStat_s* p_msg_map = obj_mapped_file.find_or_construct<MapRuleStat_s>(
shm_file.c_str())(less_s(), obj_mapped_file.get_segment_manager());
std::mutex local_mutext{}; ///<共享锁
public:
/**
* @brief 更新 key对应的整个value
* @param key My Param doc
* @param value My Param doc
* @return true
* @return false
*/
bool update(const std::string& key, const RuleStat& value) {
std::lock_guard<std::mutex> guard(local_mutext);
try {
key_object = key.c_str();
p_msg_map->operator[](key_object) = value;
return true;
} catch (const std::exception& e) {
return false;
}
}
/**
* @brief 更新 key对应value的动态 或 静态数据
* @param key
* @param value
* @param is_dynamic 是否更新动态数据
* @return true
* @return false
*/
bool update_dynamic(const std::string& key, const RuleStat& value,
bool is_dynamic = true) {
std::lock_guard<std::mutex> guard(local_mutext);
try {
key_object = key.c_str();
if (p_msg_map->find(key_object) != p_msg_map->end()) {
if (is_dynamic) {
p_msg_map->operator[](key_object).update_dynamic(value);
return true;
} else {
p_msg_map->operator[](key_object).update_static(value);
return true;
}
}
p_msg_map->operator[](key_object) = value;
return true;
} catch (const std::exception& e) {
return false;
}
}
/**
* @brief 删除 key-value
* @param key
* @return true
* @return false
*/
bool delete_data(const std::string& key) {
std::lock_guard<std::mutex> guard(local_mutext);
try {
key_delete = key.c_str();
if (p_msg_map->find(key_delete) != p_msg_map->end()) {
p_msg_map->erase(key_delete);
}
return true;
} catch (const std::exception& e) {
return false;
}
}
size_t size() {
std::lock_guard<std::mutex> guard(local_mutext);
return p_msg_map->size();
}
bool empty() {
std::lock_guard<std::mutex> guard(local_mutext);
return p_msg_map->empty();
}
/**
* @brief 统计数据存储
* @param key My Param doc
* @param value My Param doc
* @return true
* @return false
*/
bool add_stat_value(const std::string& key, const double& value) {
try {
std::lock_guard<std::mutex> guard(local_mutext);
key_object = key.c_str();
if (p_msg_map->operator[](key_object).fetch_mark) {
p_msg_map->operator[](key_object).stat_values.clear();
p_msg_map->operator[](key_object).fetch_mark = false;
}
if (p_msg_map->operator[](key_object).stat_values.size() <
stat_size_max) {
p_msg_map->operator[](key_object).stat_values.push_back(value);
}
return true;
} catch (const std::exception& e) {
return false;
}
}
/**
* @brief 获取统计数据
* @param key ruleid
* @param value 数据结果
* @return bool
*/
bool get_stat_value(const std::string& key, RuleStat& value) {
try {
std::lock_guard<std::mutex> guard(local_mutext);
key_object = key.c_str();
if (!p_msg_map->operator[](key_object).fetch_mark &&
p_msg_map->operator[](key_object).stat_values.size() >
stat_size_min) {
value.stat_values = p_msg_map->operator[](key_object).stat_values;
p_msg_map->operator[](key_object).fetch_mark = true;
return true;
}
return false;
} catch (const std::exception& e) {
return false;
}
}
/** find 共享内存数据中, vector<key> 存在的数据
* @brief
* @param ruleid My Param doc
* @return std::vector<std::string>
*/
std::vector<std::string> find_rule_id(
const std::vector<std::string>& ruleid) {
std::lock_guard<std::mutex> guard(local_mutext);
std::vector<std::string> res;
if (p_msg_map->empty()) {
return {};
}
for (auto iter1 = p_msg_map->begin(); iter1 != p_msg_map->end(); iter1++) {
auto resV = std::find(ruleid.begin(), ruleid.end(), iter1->first);
if (resV != ruleid.end()) {
res.push_back(iter1->first);
}
}
return res;
}
/** find 共享内存数据中 vector<key> 不存在的数据
* @brief
* @param ruleid My Param doc
* @return std::vector<std::string>
*/
std::vector<std::string> find_no_rule_id(
const std::vector<std::string>& ruleid) {
std::lock_guard<std::mutex> guard(local_mutext);
std::vector<std::string> res;
if (p_msg_map->empty()) {
return {};
}
for (auto iter1 = p_msg_map->begin(); iter1 != p_msg_map->end(); iter1++) {
auto resV = std::find(ruleid.begin(), ruleid.end(), iter1->first);
if (resV == ruleid.end()) {
res.push_back(iter1->first);
}
}
return res;
}
/**
* @brief 将数据转换成 string
* @return std::string;失败为 "ERROR"
*/
std::string GetDataJson() {
std::lock_guard<std::mutex> guard(local_mutext);
try {
mix_cc::json js1;
for (auto iter = p_msg_map->begin(); iter != p_msg_map->end(); iter++) {
js1[iter->first] = iter->second.invert2json();
}
return js1.dump();
} catch (const std::exception& e) {
return "ERROR";
}
}
};
} // namespace RuleStatShm