【云备份】数据管理模块
文章目录
- 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个字母,而且不清楚树枝和节点…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...

vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...

华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...