sylar高性能服务器-配置(P12-p14)内容记录

文章目录

    • p12:复杂类型解析
      • 一、方法函数
      • 二、结果展示
    • p13:复杂类型解析完善
      • 一、方法函数
      • 二、结果展示
    • p14:自定义类型解析
      • 一、方法函数
      • 二、小结

p12:复杂类型解析

​ 本节内容主要针对完了配置类中对于复杂类型的转换。之前只实现了基础类型之间的转换,而对于容器等复杂类型无法转换,所以本节实现了对于vectorstring之间的转换方式。

一、方法函数

ConfigVar

​ 之前由于只有基础类型转换,代码里面直接调用lexical_cast,这样做无法在传入复杂类型时进行解析。因此把lexical_cast的转化过程函数化,方便在外部针对特定类型的转化。

template<class T, class FromStr = LexicalCast<std::string, T>, class ToStr = LexicalCast<T, std::string>>
class ConfigVar : public ConfigvarBase {
public:typedef std::shared_ptr<ConfigVar> ptr;ConfigVar(const std::string& name, const T& default_value, const std::string& description = "") // 初始化配置名称、参数值以及参数描述:ConfigvarBase(name,description),m_val(default_value) {}std::string toString() override {   // 将参数值转换为string类型try {// return boost::lexical_cast<std::string>(m_val);return ToStr()(m_val);} catch(std::exception& e) {SYLAR_LOG_ERROR(SYLAR_LOG_ROOT()) << "ConfigVar::toString exception"<< e.what() << "convert: " << typeid(m_val).name() << " to string";}return "";}bool fromString(const std::string& val) override {  // 从string转换为参数值try {// m_val = boost::lexical_cast<T>(val);setValue(FromStr()(val));} catch (std::exception& e) {SYLAR_LOG_ERROR(SYLAR_LOG_ROOT()) << "ConfigVar::fromString exception "<< e.what() << " convert: string to " << typeid(m_val).name();}return false;}const T getValue() const { return m_val; }void setValue(const T& v) { m_val = v; }private:T m_val;
};

LexicalCast

​ 如果是int float等基础类型转化,使用下列函数,

// 基础类型转换 把F转换成T类型
template<class F, class T>
class LexicalCast {
public:T operator()(const F& v) {return boost::lexical_cast<T>(v);}
};

​ [string -> vector]。代码比较清楚,直接看注释就行。

// 复杂类型转换 偏特化[string -> vector]
template<class T>
class LexicalCast<std::string, std::vector<T>> {
public:std::vector<T> operator()(const std::string& v) {// 调用YAML中的load函数,接收一个string类型输入,将其转换成node结构YAML::Node node = YAML::Load(v);std::vector<T> vec;     // 定义结果vecstd::stringstream ss;   // 使用字符串流来获取node中的每个string值for(size_t i = 0; i < node.size(); ++ i) {ss.str("");ss << node[i];vec.push_back(LexicalCast<std::string, T>()(ss.str())); // 这里相当于调用基础类型转换,如果传入的vec里面元素是int类型,那么就是string -> int}return vec;}
};

[vector -> string]

// 复杂类型转换 偏特化[vector -> string]
template<class T>
class LexicalCast<std::vector<T>, std::string> {
public:std::string operator()(const std::vector<T>& v) {// 定义一个node容器YAML::Node node;for(auto& i : v) {node.push_back(YAML::Load(LexicalCast<T, std::string>()(i))); // 基础类型转换}std::stringstream ss;ss << node;return ss.str();}
};

二、结果展示

​ 下面代自定义了一个配置参数项g_vec_value_config,输出后载入log.yml文件,更改了g_vec_value_config里面的元素值。


sylar::ConfigVar<std::vector<int>>::ptr g_vec_value_config = sylar::Config::Lookup("system.vec", std::vector<int>{1,2,3}, "system vec");
void test_config() {// SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) << "before:" << g_int_value_config->getValue(); // SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) << "before:" << g_float_value_config->toString();auto v = g_vec_value_config->getValue();auto res = g_vec_value_config->toString();std::cout << res << std::endl;for(auto& i : v) {SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) << "before:" << i;}YAML::Node root = YAML::LoadFile("/root/Web-learning/sylar/bin/conf/log.yml");sylar::Config::LoadFromYaml(root);v = g_vec_value_config->getValue();for(auto& i : v) {SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) << "after:" << i;}// SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) << "after:" << g_int_value_config->getValue(); // SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) << "after:" << g_float_value_config->toString();
}int main(int argc, char** argv) {// test_yaml();test_config();return 0;
}

image-20231213123210283

p13:复杂类型解析完善

​ 本节内容是对上一节STL容器的完善,新增了对list、map、set、unordered_map、unordered_set的支持。由于本节的代码内容和上一节比较重复,所以简单记录一下部分内容。

一、方法函数

map

​ 注意循环的迭代方式与vector等容器不同,然后目前对于map里面的类型只支持基本类型的转换,所以后期需要按我们目前做的方式让map里面的内容支持复杂类型。

template<class T>
class LexicalCast<std::string, std::map<std::string, T>> {
public:std::map<std::string, T> operator()(const std::string& v) {YAML::Node node = YAML::Load(v);std::map<std::string,T> vec;     for(auto it = node.begin(); it != node.end(); ++ it) {ss.str("");ss << it->second;vec.insert(std::make_pair(it->first.Scalar(), LexicalCast<std::string, T>()(ss.str()))); }return vec;}
};

宏定义

​ 测试时代码重复比较大,通过下面两个宏函数简化。

#define XX(g_var,name,prefix) \{ \auto v = g_var->getValue(); \for(auto& i : v) { \SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) << #prefix " " #name ": " << i; \} \}#define XX_M(g_var,name,prefix) \{ \auto v = g_var->getValue(); \for(auto& i : v) { \SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) << #prefix " " #name ": {" << i.first << " : " << i.second << "}"; \} \}

二、结果展示

image-20231213151855855

p14:自定义类型解析

​ 本节内容主要讲解了Config解析自定义类型,和上面两节一样,处理复杂类型或者自定义类型的关键是片特化函数LexicalCast,下面是一些简单比较记录。

一、方法函数

​ 之前代码在解析yml文件时,如果遇到相同key但是类型不同,会直接忽略。比如下列代码,key:system.port的值存在两种类型,当我们使用Config::Lookup(system.port)`查找时,不知道最后找到的是谁,所以程序应该在这里报错提示。

sylar::ConfigVar<int>::ptr g_int_value_config = sylar::Config::Lookup("system.port", (int)8080, "system port");sylar::ConfigVar<float>::ptr g_int_valuex_config = sylar::Config::Lookup("system.port", (float)8080, "system port");

Lookup

​ 对该函数进行修改,核心思想就是利用dynamic_pointer_cast,如果相同key的类型不同,则会转换失败返回nullptr

auto it = s_datas.find(name); // 直接从配置容器中查找if(it != s_datas.end()) {auto tmp = std::dynamic_pointer_cast<ConfigVar<T>>(it->second);if(tmp) {SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) << "Lookup name = " << name << " exists"; } else {SYLAR_LOG_ERROR(SYLAR_LOG_ROOT()) << "Lookup name = " << name << " exists but type not " << typeid(T).name(); return nullptr;}}

再次运行可以看到已经有了报错提示

image-20231213155114465

自定义类型

​ 以下我们定义了一个Person类,希望能从log.yml文件中解析出相应的配置项。

class Person {
public:std::string m_name;int m_age = 0;bool m_sex = 0;std::string toString() const {std::stringstream ss;ss << "[Person name = " << m_name<< " age = " << m_age<< " sex = " << m_sex<< "]";return ss.str();}
};

​ 第一步肯定是去书写对应的片特化函数LexicalCast,函数里面的内容无非就是YAML::NODE类型与自定义类型之间的值传递。

namespace sylar {
// 复杂类型转换 偏特化[string -> Person]
template<>
class LexicalCast<std::string, Person> {
public:Person operator()(const std::string& v) {// 调用YAML中的load函数,接收一个string类型输入,将其转换成node结构YAML::Node node = YAML::Load(v);Person p;p.m_name = node["name"].as<std::string>();p.m_age = node["age"].as<int>();p.m_sex = node["sex"].as<bool>();return p;}
};// 复杂类型转换 偏特化[Person -> string]
template<>
class LexicalCast<Person, std::string> {
public:std::string operator()(const Person& p) {// 定义一个node容器YAML::Node node;node["name"] = p.m_name;node["age"] = p.m_age;node["sex"] = p.m_sex;std::stringstream ss;ss << node;return ss.str();}
};
}

​ 来一个测试用例

// 1.自定义类型
sylar::ConfigVar<Person>::ptr g_person = sylar::Config::Lookup("class.person", Person(), "system person");// log.yml
class:person:name: ikunage: 25sex: true

​ 输出结果:

image-20231213202609316

自定义类型与STL的嵌套

​ 设计一些复杂的用例

// 2.自定义类型与STL嵌套
sylar::ConfigVar<std::map<std::string, Person>>::ptr g_person_map = sylar::Config::Lookup("class.map", std::map<std::string, Person>(), "system map");
// 3.更加复杂的类型map<string,vector<Person>>
sylar::ConfigVar<std::map<std::string, std::vector<Person>>>::ptr g_person_vec_map = sylar::Config::Lookup("class.vec_map", std::map<std::string,  std::vector<Person>>(), "system vec_map");
// log.yml
map:person1:name: ikun2age: 252sex: trueperson2:name: ikun3age: 152sex: falsevec_map:vec1:- name: ikunage: 25sex: true- name: ikun2age: 252sex: truevec2:- name: ikun4age: 225sex: true- name: ikun21age: 2152sex: true

输出结果:

image-20231213203115964

二、小结

​ 整个配置模块到这基本完成,这几节的内容目的就是尽可能的去解析不同类型的配置内容,所以只要12节视频基本弄懂,后面两节的内容也没什么大问题。建议自己跟着视频写好代码后可以把解析过程每一步的内容打印出来,看和自己想的是否一样。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/219040.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

中伟视界:水位识别、智能化巡检、远程监控,提升智慧河道管理效率

随着现代科技的发展&#xff0c;人工智能&#xff08;AI&#xff09;算法在各行各业中的应用越来越广泛。特别是在水利行业中&#xff0c;智慧河道的运营管理已成为了一个重要的课题。本文将探讨如何利用AI算法优化智慧河道的运营效率&#xff0c;以及如何通过水位识别视频分析…

CentOS7 OpenSSL升级到OpenSSH9.5p1

原文链接&#xff1a; CentOS7 OpenSSL升级1.1.1w&#xff1b;OpenSSH 升级 9.5p1 保姆级教程 openssl从3.1.0升级到3.1.1遇到的问题 注意操作时需要联网请参考如下链接 内网服务器联网安装依赖参见我的另一篇文章 一、 前言 OpenSSH 的加密功能需要用到OpenSSL&#xff0c;所…

C语言指针基础题(二)

目录 例题一题目解析及答案 例题二题目解析及答案 例题三题目解析及答案 例题四题目解析及答案 例题五题目解析及答案 感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接 &#x1f412;&#x1f412;&#x1f412; 个人主页 &#x1f978;&#x1f978;&#x1f…

Unity | 渡鸦避难所-2 | 搭建场景并添加碰撞器

1 规范项目结构 上期中在导入一系列的商店资源包后&#xff0c;Assets 目录已经变的混乱不堪 开发过程中&#xff0c;随着资源不断更新&#xff0c;遵循一定的项目结构和设计规范是非常必要的。这可以增加项目的可读性、维护性、扩展性以及提高团队协作效率 这里先做下简单的…

智能优化算法应用:基于斑点鬣狗算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于斑点鬣狗算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于斑点鬣狗算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.斑点鬣狗算法4.实验参数设定5.算法结果6.…

攻防世界-web-upload

1. 题目描述 打开链接&#xff0c;是这样的一个注册界面 先试着注册一个账号看看&#xff0c;这里简单操作&#xff0c;注册test/test&#xff0c;注册完后进行登录 登录成功后进入到这样一个文件上传界面。当前从界面上得到的信息暂时就是这些了。 2. 思路分析 既然存在上传…

【ret2hbp】一道板子测试题 和 SCTF2023 - sycrpg

前言 ret2hbp 主要是利用在内核版本 v6.2.0 之前&#xff0c;cpu_entry_area mapping 区域没有参与随机化的利用。其主要针对的场景如下&#xff1a; 1&#xff09;存在任意地址读&#xff0c;泄漏内核地址 2&#xff09;存在无数次任意地址写&#xff0c;泄漏内核地址并提权…

HCIA-WLAN V3.0,那些重点要点

一、WLAN各个标准&#xff0c;工作频段&#xff0c;理论速率。 二、OFDM和OFDMA&#xff0c;工作频段&#xff0c;空间流。 三、三种帧类型&#xff1a;管理帧、控制帧、数据帧&#xff0c;CAPWAP报文和端口。 四、帧间间隔&#xff0c;波束成形&#xff0c;信道绑定&#xff0…

接口测试要测试什么?怎么测?

本文主要分为两个部分&#xff1a; 第一部分&#xff1a;主要从问题出发&#xff0c;引入接口测试的相关内容并与前端测试进行简单对比&#xff0c;总结两者之前的区别与联系 第二部分&#xff1a;主要介绍为什么要做接口测试&#xff0c;并简单总结接口持续集成和接口质量评估…

正确看待鸿蒙不兼容Android,这不是趋势?

华为可能明年推出不兼容安卓的鸿蒙版本。11月20日&#xff0c;据澎湃新闻报道&#xff0c;一华为相关人士表示&#xff0c;推出时间还不确定&#xff0c;未来IOS、鸿蒙、安卓将为三个各自独立的系统。 稍早前据证券时报报道&#xff0c;有业内人士亦表示&#xff1a;“华为内部…

Re59:读论文 Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks

诸神缄默不语-个人CSDN博文目录 诸神缄默不语的论文阅读笔记和分类 论文名称&#xff1a;Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks 模型开源地址&#xff1a;https://huggingface.co/facebook/rag-token-nq ArXiv下载地址&#xff1a;https://arxi…

Linux——MySQL数据库的使用

访问MySQL数据库 MySOL数据库系统也是一个典型的C/S&#xff08;客户端/服务器&#xff09;架构的应用&#xff0c;要访问MySOL数据库 需要使用专门的客户端软件&#xff0c;在Linux系统中&#xff0c;最简单、易用的MySQL.客户端软件是其自带的mysql 命令工具。 登录到MySQL服…

关于Cython生成的so动态链接库逆向

来个引子&#xff1a;TPCTF的maze题目 如何生成这个so文件 为了研究逆向&#xff0c;我们先搞个例子感受一下生成so的整个过程&#xff0c;方便后续分析 创建对应python库文件 testso.py def test_add(a,b):a int(a)b int(b)return a bdef test_calc(li):for i in range…

逆向思考 C. Fence Painting

Problem - 1481C - Codeforces 思路&#xff1a;逆序考虑&#xff0c;因为每一块木板都是被最后一次粉刷所决定的。 从后往前开始&#xff0c;对于 c i c_i ci​来说&#xff0c; 如果这个颜色还有没有涂的木板&#xff0c;那么涂到其中一个木板即可如果这个颜色下没有未涂的…

系统思考与啤酒游戏经营沙盘

结束一家汽车零配件公司《系统思考与啤酒游戏经营沙盘》的内训课&#xff0c;4个小组基本上都有共同的心智模式&#xff0c;这也代表团队有一些集体的盲点。不仅仅对啤酒游戏经营沙盘做了复盘&#xff0c;同时也借用学员画出的系统环路图完成真实案例的研讨以及团队共识&#x…

从零开始学机器学习,这些学习网站让你事半功倍!

介绍&#xff1a;机器学习是人工智能&#xff08;AI&#xff09;和计算机科学的一个分支&#xff0c;它专注于使用数据和算法&#xff0c;模仿人类学习的方式&#xff0c;逐步提高自身的准确性。更具体来说&#xff0c;机器学习是一门关于数据学习的科学技术&#xff0c;它能帮…

功能更新|免费敏捷工具Leangoo领歌私有部署新增第三方身份认证和API对接

Leangoo领歌是一款永久免费的专业的敏捷开发管理工具&#xff0c;提供端到端敏捷研发管理解决方案&#xff0c;涵盖敏捷需求管理、任务协同、进展跟踪、统计度量等。 Leangoo支持敏捷研发管理全流程&#xff0c;包括小型团队敏捷开发&#xff0c;规模化敏捷SAFe&#xff0c;Scr…

MySQL笔记-第11章_数据处理之增删改

视频链接&#xff1a;【MySQL数据库入门到大牛&#xff0c;mysql安装到优化&#xff0c;百科全书级&#xff0c;全网天花板】 文章目录 第11章_数据处理之增删改1. 插入数据1.1 实际问题1.2 方式1&#xff1a;VALUES的方式添加1.3 方式2&#xff1a;将查询结果插入到表中 2. 更…

三只松鼠坚持的“高端性价比”,也是零食行业通往未来的门票?

文 | 螳螂观察 作者 | 易不二 没有成功的企业&#xff0c;只有时代的企业。 从全球商业数百年的发展历史来看&#xff0c;一百年间有无数企业演绎了“诞生→发展→巅峰→衰亡”的宿命。即便此间已经走到了世界500强的企业&#xff0c;到现在存活下来的也仅有3%。 时代的潮流…

2023自动化测试框架大对比:哪个更胜一筹?

所谓工欲善其事&#xff0c;必先利其器&#xff0c;在进行自动化测试时&#xff0c;选择一个合适的框架是至关重要的。因为一个好的测试框架可以大大提高测试效率&#xff0c;减少我们很多工作量。在选择框架之前&#xff0c;我们通常需要对不同的框架进行对比&#xff0c;以便…