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.rhkb.cn/news/216420.html

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

相关文章

最近面试了一位5年的测试,一问三不知,还反怼我...

最近看了很多简历&#xff0c;很多候选人年限不小&#xff0c;但是做的都是一些非常传统的项目&#xff0c;想着也不能通过简历就直接否定一个人&#xff0c;何况现在大环境越来 越难&#xff0c;大家找工作也不容易&#xff0c;于是就打算见一见。 在沟通中发现&#xff0c;由…

Linux高级管理--安装MySQL数据库系统

MySQL服务基础 MySQL.是一个真正的多线程、多用户的SQL数据库服务&#xff0c;凭借其高性能、高可靠和易于使 用的特性&#xff0c;成为服务器领域中最受欢迎的开源数据库系统。在2008年以前&#xff0c;MySOL项目由MySQL AB公司进行开发&#xff0c;发布和支持&#xff0c;之后…

产品表结构分析

一个项目之中&#xff0c;会有很多数据&#xff0c;众多数据之间也存在这各种关系&#xff0c;如何依据这些关系设计出更符合实际且适合的表及之间的关联关系也是我们所必须学习的 一、常见部门表结构分析 几乎所有框架里面都有一张部门表&#xff0c;我们先来看一下他的结构&…

逆向思考 C. Fence Painting

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

使用selenium的edge浏览器登录某为

互联网上基本都是某哥的用法&#xff0c;其实edge和某哥的用法是一样的就有一下参数不一样。 一、运行环境 Python&#xff1a;3.7 Selenium&#xff1a;4.11.2 Edge&#xff1a;版本 120.0.2210.61 (正式版本) (64 位) 二、执行代码 from time import sleepfrom selenium…

GB28181学习(十八)——图像抓拍

前言 本文主要介绍图像抓拍功能&#xff0c;通过自研的sip库&#xff08;mysipsdk.dll&#xff09;对接真实设备&#xff0c;使用http方式实现图像数据传输&#xff0c;最终达到图像抓拍与保存的目的。 基本要求 图像格式宜使用JPEG&#xff1b;图像分辨率宜采用与主码流相同…

【JMeter】使用nmon进行性能资源监控

一、前言 ​ 在工作中可能会遇到需要在压测的时候对Linux服务器进行性能资源监控的情况。这时可以用nmon来对服务器进行监控。 二、nmon的下载安装 1.查看系统信息 shell cat /etc/os-release结果为 shell PRETTY_NAME"Debian GNU/Linux 12 (bookworm)" NAME&qu…

动物姿态估计:微调 YOLOv8 姿态模型

动物姿态估计是计算机视觉的一个研究领域&#xff0c;是人工智能的一个子领域&#xff0c;专注于自动检测和分析图像或视频片段中动物的姿势和位置。目标是确定一种或多种动物的身体部位&#xff08;例如头部、四肢和尾巴&#xff09;的空间排列。这项技术具有广泛的应用&#…

【大数据】Hadoop生态未来发展的一些看法

大数据的起源 谷歌在2003到2006年间发表了三篇论文&#xff0c;《MapReduce: Simplified Data Processing on Large Clusters》&#xff0c;《Bigtable: A Distributed Storage System for Structured Data》和《The Google File System》介绍了Google如何对大规模数据进行存储…

MATLAB基础运算

矩阵和数字相乘 就是矩阵里面每个元素跟这个数字乘一遍&#xff0c;无论是点乘还是叉乘&#xff0c;对于这个都一样。 >> Aones(3) A 1 1 11 1 11 1 1 >> 10*A ans 10 10 1010 10 1010 10 10 矩阵和矩阵叉乘 能不能相…

什么是接口测试?如何做接口测试

接口测试是指对系统或应用程序接口进行测试&#xff0c;以验证接口的功能、可靠性、性能、安全性等方面的需求是否被满足。接口测试可以用于测试不同系统、模块、组件之间的交互和通信&#xff0c;包括 Web 接口、网络接口、数据库接口等。其重点是测试数据传输、数据格式、数据…

excel做预测的方法集合

一. LINEST函数 首先&#xff0c;一元线性回归的方程&#xff1a; y a bx 相应的&#xff0c;多元线性回归方程式&#xff1a; y a b1x1 b2x2 … bnxn 这里&#xff1a; y - 因变量即预测值x - 自变量a - 截距b - 斜率 LINEST的可以返回回归方程的 截距(a) 和 斜…

MySQL基础笔记

MySQL 1. SQL1.1 SQL-DDL语句1.1.1 数据库操作1.1.2 表操作 1.2 MySQL-DML语句1.3 MySQL-DQL语句1.3.1 基本查询1.3.2 条件查询1.3.3 聚合函数1.3.4 分组查询1.3.5 排序查询1.3.6 分页查询 1.4 MySQL-DCL语句1.4.1 管理用户1.4.2 权限控制 2. 函数2.1 字符串函数2.2 数值函数2.…

mybatis动态SQL-choose-when-otherwise

1、建库建表 create database mybatis-example; use mybatis-example; create table emp (empNo varchar(40),empName varchar(100),sal int,deptno varchar(10) ); insert into emp values(e001,张三,8000,d001); insert into emp values(e002,李四,9000,d001); insert into…

性能测试、负载测试、压力测试之间的差异!

1、什么是性能测试 性能测试是一种用于确定计算机、网络或设备速度的测试。它通过在不同的负载场景中传递不同的参数来检查系统组件的性能。 2、什么是负载测试 负载测试是在任何应用程序或网站上模拟实际用户负载的过程。它检查应用程序在正常和高负载期间的行为。当开发项目…

Gin之GORM 操作数据库(MySQL)

GORM 简单介绍 GORM 是 Golang 的一个 orm 框架。简单说&#xff0c;ORM 就是通过实例对象的语法&#xff0c;完成关系型数据库的操作的技术&#xff0c;是"对象-关系映射"&#xff08;Object/Relational Mapping&#xff09; 的缩写。使用 ORM框架可以让我们更方便…

医保电子凭证在项目中的集成应用

随着医保电子凭证使用普及&#xff0c;医疗行业的各个场景都要求支持医保码一码通办&#xff0c;在此分享一下&#xff0c;在C#和js中集成医保电子凭证的demo 供有需要的小伙伴参考。 一、项目效果图 在c#中集成医保电子凭证效果 在js中集成医保电子凭证效果 二、主要代码 c#…

【漏洞复现】FLIR AX8红外线热成像仪命令执行漏洞

漏洞描述 eledyne FLIR 设计、开发、制造以及强大的传感和意识技术。自透射热图像、可见光图像、可见频率分析、来自测量和诊断的先进威胁测量系统以及日常生活的创新解决方案。 Teledyne FLIR 提供多种产品用于政府、国防、工业和商业市场。我们的产品,紧急救援人员,军事人…

分割均衡字符串 - 华为OD统一考试(C卷)

OD统一考试&#xff08;C卷&#xff09; 分值&#xff1a; 100分 题解&#xff1a; Java / Python / C 题目描述 均衡串定义:字符串只包含两种字符&#xff0c;且两种字符的个数相同。 给定一个均衡字符串&#xff0c;请给出可分割成新的均衡子串的最大个数。 约定字符串中只…

机器学习三个基本要素:优化算法

在确定了训练集 D、假设空间 ℱ 以及学习准则后&#xff0c;如何找到最优的模型&#x1d453;(x,θ∗) 就成了一个最优化&#xff08;Optimization&#xff09;问题。机器学习的训练过程其实就是最优化问题的求解过程。 参数与超参数 在机器学习中&#xff0c;优化又可以分为参…