【云备份】数据管理模块
文章目录
- 1. 数据管理模块要管理什么数据?
- 2. 数据管理模块如何管理数据?
- 3. 数据管理模块的具体实现
- BackupInfo 数据信息类
- NewBackupInfo —— 获取各项属性信息
- DataManager 数据管理类
- 构造函数
- 析构函数
- insert —— 新增
- update —— 修改
- GetOneByURL——通过URL获取单个数据
- GetOneByURL——通过realpath获取单个数据
- GETALL —— 获取所有
- Storage —— 持久化存储实现
- 具体代码实现
- data.hpp
1. 数据管理模块要管理什么数据?
1.文件实际存储路径
(当客户端下载文件时,则从文件中读取数据进行响应)
2. 文件压缩包存放路径名
(如果一个文件是非热点文件,就会被压缩,则就为压缩包路径名称)
3.文件是否被压缩的标志位
(判断文件是否已经被压缩了)
4.文件大小
5.文件最后一次修改时间
6.文件最后一次访问时间
7. 文件访问URL中的资源路径path
2. 数据管理模块如何管理数据?
1.用于数据信息访问
(使用hash表在内存中管理数据,以url的path作为key值,来查询内部存储的数据,查询速度快)
2.持久化存储管理
使用json序列化 将 所有数据信息 保存在文件中
3. 数据管理模块的具体实现
BackupInfo 数据信息类
数据信息结构体 BackupInfo_t 包含
pack_flag ——是否压缩标志
fsize ——文件大小
latime ——最后一次访问时间
lmtime ——最后一次修改时间
real_path ——文件实际存储路径名称
pack_path ——压缩包存储路径名称
url_path ——请求资源路径
NewBackupInfo —— 获取各项属性信息
将 NewBackupInfo 函数的参数 realpath路径名 传入 ,实例化一个 FileUtil类的对象
由于是新创建的文件,所以不用压缩
分别调用 FileUtil类 中的 Filesize(文件大小) 、 LastMtime( 文件最后一次修改时间)、 LastATime( 文件最后一次访问时间)
传入的 realpath 就为 文件实际存储路径名称
想要获取压缩包存储路径名称(pack_path) 则需将文件的前缀名换为 ./pack 后缀为换为.lz
实例化一个 Config类的对象,借助 Config类 的GetpackDir(压缩包存放路径)、GetPackFileSuffix(压缩包后缀名称)
通过前缀 、后缀 再加上 中间的文件名称 即可 获得 压缩包存储路径名称
借助 Config类 的GetDownloadPrefix(URL前缀路径) ,再加上文件名称 即可获得请求资源路径
DataManager 数据管理类
构造函数
输入 man pthread_rwlock_init 查看锁的初始化
第一个参数为 rwlock 为 读写锁
第二个参数为 attr 为属性
将属性设置为NULL即可
析构函数
输入 man pthread_rwlock_init 也可查看锁的销毁
insert —— 新增
insert插入,想要进行修改就需要 加写锁 即修改table
table作为一个哈希表, info.url 为 key值 info作为value
最后进行解锁即可
update —— 修改
哈希表的数据不会重复,所以当key值相同时,info会覆盖之前的数据
所以插入和修改的代码是相同的
GetOneByURL——通过URL获取单个数据
先加锁
然后再使用find 查找key值为url的数据
若查找到末尾都没有找到 则返回 false
若找到了 先解锁 再返回 url对应的info
GetOneByURL——通过realpath获取单个数据
realpath不是key值,而是info中的一个成员变量, 所以不能使用find来查找
先加锁 再遍历整个哈希表来查找
若找到了对应的realpath ,则将对应的value放入info中 并解锁 返回true
若遍历整个哈希表 都没找到 ,则解锁 返回false
GETALL —— 获取所有
同样是先加锁 再遍历整个哈希表
每遍历一次,就向arry数组中插入当前哈希表数据对应的info
遍历完后 进行解锁 返回 true即可
Storage —— 持久化存储实现
先定义 一个 BackupInfo 类型的 arry数组
并调用 GetAll 获取所有数据 放入 arry数组中
遍历整个arry数组,将当前arry数组中的元素 的 是否压缩标志、 文件大小、最后一次访问时间、 最后一次修改时间、文件实际存储路径名称、 压缩包存储路径名称、请求资源路径 全部放入 item 中
再把 数组元素 item 添加到 root中
定义一个string类型的变量body
通过之前实现好的 Serialize 函数 进行序列化 即将root中的数据 转化到body文件中
通过 _backup_file 数据持久化存储文件 实例化一个对象
再通过FileUtil类中 的 Setcontent 函数 将body写入到 _backup_file 文件中
具体代码实现
data.hpp
#ifndef _MY_DATA_
#define _MY_DATA_
#include<unordered_map>
#include<pthread.h>
#include"config.hpp"namespace cloud
{typedef struct BackupInfo{bool pack_flag;//压缩标志size_t fsize; //文件大小time_t mtime; //最后一次修改时间time_t atime; //最后一次访问时间std::string real_path;//文件实际存储路径std::string pack_path;//压缩包存储路径名称std::string url; //请求资源路径bool NewBackupInfo(const std::string &realpath)//获取各项属性信息{FileUtil fu(realpath);if(fu.Exists()==false){std::cout<<"new backupinfo file not exists" <<std::endl;return false;}Config* config=Config::GetInstance();//创建对象std::string packdir=config->GetPackDir();//压缩包存放路径std::string packsuffix=config->GetPackFileSuffix();//压缩包后缀名称std::string download_prefix =config->GetDownloadPrefix();//URL前缀路径this->pack_flag=false;this->fsize=fu.FileSize();this->mtime=fu.LastMTime();this->atime=fu.LastATime();this->real_path=realpath; this->pack_path = packdir+fu.FileName()+packsuffix;// ./backdir/a.txt -> ./packdir/a.txt.lzthis->url=download_prefix + fu.FileName();//./backdir/a.txt -> /download/a.txt return true;}}BackupInfo;class DataManger{private:std::string _backup_file;//数据持久化存储文件 pthread_rwlock_t _rwlock;//读写锁 std::unordered_map<std::string,BackupInfo> _table;//哈希表public:DataManger()//构造函数{ _backup_file=Config::GetInstance()->GetBackupFile();//数据信息存放文件pthread_rwlock_init(&_rwlock,NULL);//对读写锁初始化}~DataManger()//析构函数{pthread_rwlock_destroy(&_rwlock);//对读写锁进行销毁}bool Insert(const BackupInfo &info)//新增{ pthread_rwlock_wrlock(&_rwlock);//加写锁_table[info.url]=info;pthread_rwlock_unlock(&_rwlock);//解锁Storage();return true;}bool update(const BackupInfo& info)//更新{pthread_rwlock_wrlock(&_rwlock);//加写锁_table[info.url]=info;pthread_rwlock_unlock(&_rwlock);//解锁Storage();return true;}bool GetOneByURL(const std::string &url,BackupInfo*info)//通过URL获取单个数据{pthread_rwlock_wrlock(&_rwlock);//加写锁//因为url是key值 所以可以直接通过key值来进行查找auto it=_table.find(url);if(it==_table.end()){return false;}*info= it->second;//获取url对应的infopthread_rwlock_unlock(&_rwlock);//解锁return true;} bool GetOneByRealPath(const std::string &realpath ,BackupInfo*info)//通过realpath获取单个数据{pthread_rwlock_wrlock(&_rwlock);//加写锁auto it=_table.begin();for(;it!=_table.end();++it)//遍历{if(it->second.real_path==realpath){*info=it->second;pthread_rwlock_unlock(&_rwlock);//解锁return true;}}pthread_rwlock_unlock(&_rwlock);//解锁return false;}bool GetAll(std::vector<BackupInfo>*arry) //获取所有{pthread_rwlock_wrlock(&_rwlock);//加写锁auto it=_table.begin();for(;it!=_table.end();++it)//遍历{arry->push_back(it->second);}pthread_rwlock_unlock(&_rwlock);//解锁return true;}bool Storage()//持久化存储实现{//获取所有数据 std::vector<BackupInfo> arry;this->GetAll(&arry);//获取所有数据放入arry中//添加到json::value中Json::Value root; for(int i=0;i<arry.size();i++){Json::Value item; item["pack_flag"]= arry[i].pack_flag;item["fsize"]= (Json::Int64)arry[i].fsize;item["atime"]= (Json::Int64)arry[i].atime;item["mtime"]= (Json::Int64)arry[i].mtime;item["real_path"]= arry[i].real_path;item["pack_path"]= arry[i].pack_path;item["url"]= arry[i].url; root.append(item); //添加数组元素item } // 对json::value 序列化 std::string body;JsonUtil::Serialize(root,&body);//序列化 //写文件FileUtil fu(_backup_file);//数据持久化存储文件 fu.Setcontent(body);return true;}};}#endif
相关文章:
【云备份】数据管理模块
文章目录 1. 数据管理模块要管理什么数据?2. 数据管理模块如何管理数据?3. 数据管理模块的具体实现BackupInfo 数据信息类NewBackupInfo —— 获取各项属性信息 DataManager 数据管理类构造函数析构函数insert —— 新增update —— 修改GetOneByURL——…...
C++ :const修饰成员函数
常函数: 常函数: 成员函数后加const后我们称为这个函数为常函数 常函数内不可以修改成员属性 成员属性声明时加关键字mutable后,在常函数中依然可以修改 属性可修改: class Person { public: void showPerson() …...
论文阅读:“Model-based teeth reconstruction”
文章目录 AbstractIntroductionTeeth Prior ModelData PreparationParametric Teeth Model Teeth FittingTeeth Boundary Extraction Reference Abstract 近年来,基于图像的人脸重建方法日趋成熟。这些方法可以捕捉整个面部或面部特定区域(如头发、眼睛…...
Web 安全之证书透明(Certificate Transparency)详解
目录 证书透明性的概念 数字证书和颁发机构 证书透明的起源 证书透明的工作原理 证书透明的实现方法 证书透明的优点 浏览器和客户端对证书透明的支持情况 小结 证书透明(Certificate Transparency, CT)是网络安全领域中的一个重要概念ÿ…...
智能优化算法应用:基于蜻蜓算法无线传感器网络(WSN)覆盖优化 - 附代码
智能优化算法应用:基于蜻蜓算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于蜻蜓算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.蜻蜓算法4.实验参数设定5.算法结果6.参考文献7.MATLAB…...
【古诗生成AI实战】之二——项目架构设计
[1] 项目架构 在我们深入古诗生成AI项目的具体实践之前,让我们首先理解整个项目的架构。本项目的代码流程主要分为三个关键阶段: 1、数据处理阶段; 2、模型训练阶段; 3、文本生成阶段。 第一步:在数据处理阶段…...
动态网页从数据库取信息,然后展示。
把数据库的驱动放在bin目录下。 通过servlet 读取数据库的内容,生成session,然后跨页面传给展示页。 package src;import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSe…...
单片机学习3——数码管
数码管,根据内部结构,可分为共阴极数码管和共阳极数码管。七段发光管加上一个小数点,共计8段。因此,我们对它编程的时候,刚好是用一个字节。 数码管的显示方式: 1)静态显示; 2&…...
数据库表结构导出成Excel或Word格式
前言 该工具主要用于导出excel、word,方便快速编写《数据库设计文档》,同时可以快速查看表的结构和相关信息。 本博客仅作记录,最新源码已经支持多种数据库多种格式导出,有兴趣的可移步源码作者地址:https://gitee.co…...
School training competition ( Second )
A. Medium Number 链接 : Problem - 1760A - Codeforces 就是求三个数的中位数 : #include<bits/stdc.h> #define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); #define endl \nusing namespace std; typedef long long LL; const int N 2e510;inline void …...
深度解析 Docker Registry:构建安全高效的私有镜像仓库
文章目录 什么是Docker Registry?Docker Hub vs. 私有RegistryDocker Hub:私有Registry: 如何构建私有Docker Registry?步骤一:安装Docker Registry步骤二:配置TLS(可选)步骤三&…...
leetcode 不同的二叉搜索树
给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。 示例 1: 输入:n 3 输出:5 示例 2: 输入:n 1 输出:…...
通俗易懂的spring Cloud;业务场景介绍 二、Spring Cloud核心组件:Eureka 、Feign、Ribbon、Hystrix、zuul
文章目录 通俗易懂的spring Cloud一、业务场景介绍二、Spring Cloud核心组件:Eureka三、Spring Cloud核心组件:Feign四、Spring Cloud核心组件:Ribbon五、Spring Cloud核心组件:Hystrix六、Spring Cloud核心组件:Zuul七…...
大数据预处理技术
文章目录 前言 大数据技术成为前沿专业 也是现在甚至未来的朝阳产业,大数据有分别是 数据预处理 数据存储 大数据处理和分析 数据可视化 部分组成 ,大数据行业有数据则称王,大数据的核心是数据本身 怎么获取有价值的数据呢?本章讲…...
跳表的学习记录
跳表(Skip List)是一种数据结构,它通过在多个层次上添加额外的前向指针来提高有序数据的搜索效率。跳表与其他常见的有序数据结构(如二叉搜索树、平衡树如AVL树和红黑树、B树等)相比,具有其独特的优缺点&am…...
电子学会C/C++编程等级考试2022年09月(二级)真题解析
C/C++等级考试(1~8级)全部真题・点这里 第1题:统计误差范围内的数 统计一个整数序列中与指定数字m误差范围小于等于X的数的个数。 时间限制:5000 内存限制:65536输入 输入包含三行: 第一行为N,表示整数序列的长度(N <= 100); 第二行为N个整数,整数之间以一个空格分…...
如何使用nginx部署静态资源
Nginx可以作为静态web服务器来部署静态资源,这个静态资源是指在服务端真实存在,并且能够直接展示的一些文件数据,比如常见的静态资源有html页面、css文件、js文件、图片、视频、音频等资源相对于Tomcat服务器来说,Nginx处理静态资…...
lua的gc原理
lua垃圾回收(Garbage Collect)是lua中一个比较重要的部分。由于lua源码版本变迁,目前大多数有关这个方面的文章都还是基于lua5.1版本,有一定的滞后性。因此本文通过参考当前的5.3.4版本的Lua源码,希望对Lua的GC算法有一个较为详尽的探讨。 L…...
redis作为缓存详解
目录 前言: 为什么说关系型数据库性能不高 如何提高MySQL并发量 缓存更新策略 定期更新 实时更新 内存淘汰策略 Redis内置的淘汰策略 缓存常见问题 缓存预热 缓存穿透 缓存雪崩 缓存击穿 前言: 对于缓存的理解,缓存目的就是为了…...
231127 刷题日报
这周值班。。多少写道题吧,保持每天的手感。老婆给买了lubuladong纸质书,加油卷。 1. 131. 分割回文串 写个这个吧,钉在耻辱柱上的题。 为啥没写出来: 1. 递归树没画对 把树枝只看做是1个字母,而且不清楚树枝和节点…...
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
