【云备份】服务端模块-数据管理模块

文章目录

代码

#ifndef __MY_DATA__
#define __MY_DATA__
#include <unordered_map>
#include <pthread.h>
#include "fileUtil.hpp"
#include "config.hpp"

namespace cloudBackup
{
	// 已备份的文件的属性信息  backup file Attribute information
	typedef struct BackupAInfo // 都需要管理哪些信息
	{
		bool _isZipped;			 // 是否被压缩
		size_t _fsize;			 // 文件大小
		time_t _atime;			 // 最后一次访问
		time_t _ctime;			 // 最后一次状态改变
		time_t _mtime;			 // 最后一次修改
		std::string _backupPath; // 备份文件存放路径
		std::string _zipPath;	 // 压缩包存放路径
		std::string _url;		 // 客户端http请求url路径 demo

		// BackupAInfo对象obj调用此函数 目的是设置filename文件的属性信息
		bool NewBackupAInfo(const std::string &filename)
		{
			// 无法为不存在的文件添加属性信息
			FileUtil fileUtil(filename);
			if (fileUtil.Exists() == false)
			{
				Log::log(Error, "BackupInfo::NewBackupAInfo file not exists!: %s: %d", strerror(errno), errno);
				return false;
			}

			// 从配置文件读取相关信息
			Config *config = Config::GetInstance();
			std::string zipDir = config->GetZipDir();
			std::string zipSuffix = config->GetZipSuffix();
			std::string urlPrefix = config->GetUrlPrefix();

			this->_isZipped = false;
			this->_fsize = fileUtil.FileSize();
			this->_atime = fileUtil.LastATime();
			this->_ctime = fileUtil.LastCTime();
			this->_mtime = fileUtil.LastMTime();
			this->_backupPath = filename;
			this->_zipPath = zipDir + fileUtil.FileName() + zipSuffix; // ./zipDir/a.txt.lz
			this->_url = urlPrefix + fileUtil.FileName();			   // download/a.txt

			return true;
		}

		void showMsg()
		{
			std::cout << "_isZipped: " << _isZipped << std::endl;
			std::cout << "_fsize: " << _fsize << std::endl;
			std::cout << "_atime: " << _atime << std::endl;
			std::cout << "_ctime: " << _ctime << std::endl;
			std::cout << "_mtime: " << _mtime << std::endl;
			std::cout << "_backupPath: " << _backupPath << std::endl;
			std::cout << "_zipPath: " << _zipPath << std::endl;
			std::cout << "_url: " << _url << std::endl;
		}
	} BackupAInfo;

	// 数据管理类 怎么管理
	class DataManager
	{
	private:
		// 该文件存储诸多已备份文件的属性信息 json对象序列化成str保存在该文件
		std::string _backupAInfoFile;
		// 使用hash表在内存中管理数据 以url作为key值--查询速度快
		std::unordered_map<std::string, BackupAInfo> _table;
		// 读写锁:读共享 写互斥
		pthread_rwlock_t _rwlock;
		/*
		以URL为key BackupAInfo为val 使用哈希表管理 查询速度快
		url作为key:浏览器下载文件的时候总是以url作为请求
		*/
	public:
		DataManager()
		{
			// 成员属性初始化
			_backupAInfoFile = Config::GetInstance()->GetBackupAInfoFName(); // 获取存放备份文件属性信息的文件
			pthread_rwlock_init(&_rwlock, NULL);							 // 初始化读写锁
			InitLoad();
		}

		~DataManager()
		{
			pthread_rwlock_destroy(&_rwlock); // 销毁读写锁
		}

		// 每次程序运行前 从 存放备份文件属性信息的文件中 中读取数据至内存中的哈希表
		// 服务端初次运行时 _backupAInfoFile文件不存在 函数一路调用直到setContent才创建backupAInfo.dat
		// 服务端启动后 当备份文件增多 里面的信息就会不断增多
		bool InitLoad() // 备份文件属性信息 从文件->内存
		{
			// 1. 将备份文件属性信息读取出来存至content binary->str
			FileUtil fileUtil(_backupAInfoFile);
			// 存放备份文件属性信息的文件 不存在(首次启动) 无须load 函数返回
			if (fileUtil.Exists() == false)
			{
				Log::log(Info, "DataManager::InitLoad file not exist, no need to load: %s: %d", strerror(errno), errno);
				return true;
			}
			std::string content;
			fileUtil.GetContent(&content);

			// 2. str反序列化成json对象 str->json
			Json::Value root;
			JsonUtil::Deserialize(content, &root);

			// 3. 将反序列化得到的Json::Value中的数据添加到table中
			for (int i = 0; i < root.size(); i++)
			{
				BackupAInfo info;
				info._isZipped = root[i]["_isZipped"].asBool();
				info._fsize = root[i]["_fsize"].asInt64();
				info._atime = root[i]["_atime"].asInt64();
				info._ctime = root[i]["_ctime"].asInt64();
				info._mtime = root[i]["_mtime"].asInt64();
				info._zipPath = root[i]["_zipPath"].asString();
				info._backupPath = root[i]["_backupPath"].asString();
				info._url = root[i]["_url"].asString();

				Insert_Table(info);
			}
			return true;
		}

		// 将一个个 文件属性信息插入到表中
		bool Insert_Table(const BackupAInfo &info)
		{
			pthread_rwlock_wrlock(&_rwlock);
			_table[info._url] = info;
			pthread_rwlock_unlock(&_rwlock);

			Storage();
			return true;
		}

		// 每次数据新增或修改后重新进行持久化存储 避免数据丢失
		bool Storage()
		{
			// 1. 获取当前表中的所有的BackupAInfo
			std::vector<BackupAInfo> array;
			this->GetAllBackupAInfo(&array);

			// 2. 添加到Json::Value
			Json::Value root;
			for (int i = 0; i < array.size(); i++)
			{
				Json::Value item;
				item["_isZipped"] = array[i]._isZipped;
				item["_fsize"] = (Json::Int64)array[i]._fsize;
				item["_atime"] = (Json::Int64)array[i]._atime;
				item["_ctime"] = (Json::Int64)array[i]._ctime;
				item["_mtime"] = (Json::Int64)array[i]._mtime;
				item["_backupPath"] = array[i]._backupPath;
				item["_zipPath"] = array[i]._zipPath;
				item["_url"] = array[i]._url;

				root.append(item); // 添加数组元素
			}

			// 3. Json::Value序列化成字符串
			std::string content;
			JsonUtil::Serialize(root, &content);

			// 4. 写文件
			FileUtil fileUtil(_backupAInfoFile);
			fileUtil.SetContent(content);

			return true;
		}

		// 获取当前表中的所有的BackupAInfo 存入array
		bool GetAllBackupAInfo(std::vector<BackupAInfo> *array)
		{
			pthread_rwlock_wrlock(&_rwlock);

			for (auto it = _table.begin(); it != _table.end(); ++it)
				array->push_back(it->second);

			pthread_rwlock_unlock(&_rwlock);
			return true;
		}

		bool Update(const BackupAInfo &info)
		{
			pthread_rwlock_wrlock(&_rwlock);
			_table[info._url] = info;
			pthread_rwlock_unlock(&_rwlock);
			Storage();
			return true;
		}

		bool GetOneByURL(const std::string &url, BackupAInfo *info)
		{
			pthread_rwlock_wrlock(&_rwlock);
			// url是key值 直接通过find进行查找
			auto it = _table.find(url);
			if (it == _table.end())
			{
				pthread_rwlock_unlock(&_rwlock);
				Log::log(Error, "DataManager::GetOneByURL not find url-?: %s: %d", strerror(errno), errno);
				return false;
			}
			*info = it->second;
			pthread_rwlock_unlock(&_rwlock);
			return true;
		}

		bool GetOneByRealPath(const std::string &filename, BackupAInfo *info)
		{
			pthread_rwlock_wrlock(&_rwlock);
			for (auto it = _table.begin(); it != _table.end(); ++it)
			{
				if (it->second._backupPath == filename)
				{
					*info = it->second;
					pthread_rwlock_unlock(&_rwlock);
					return true;
				}
			}
			pthread_rwlock_unlock(&_rwlock);
			Log::log(Error, "DataManager::GetOneByRealPath not find realpath-?: %s: %d", strerror(errno), errno);

			return false;
		}
	};
}
#endif //__MY_DATA__

测试代码

#include "fileUtil.hpp"
#include "jsonUtil.hpp"
#include "config.hpp"
#include "data.hpp"
// #include "hot.hpp"
// #include "service.hpp"
#include <thread>
using namespace std;
void DataTest(const std::string &filename)
{
	// 假设命令行参数传来的文件是备份文件 为该文件设置备份信息
	std::cout << "NewBackupAInfo " << std::endl;
	cloudBackup::BackupAInfo info;
	info.NewBackupAInfo(filename);
	info.showMsg();
	std::cout << std::endl;

	// 将备份文件信息添加到表中 与url形成映射
	// dataManager一旦实例化 调用构造 获取存放备份文件属性信息的文件名
	// 把备份文件属性信息从文件加载到内存(hashMap)
	std::cout << " GetOneByURL" << std::endl;
	cloudBackup::DataManager dataManager;
	dataManager.Insert_Table(info);
	cloudBackup::BackupAInfo tmp;
	dataManager.GetOneByURL("/download/makefile", &tmp);
	tmp.showMsg();
	std::cout << std::endl;

	std::cout << "GetAllBackupAInfo " << std::endl;
	std::vector<cloudBackup::BackupAInfo> array;
	dataManager.GetAllBackupAInfo(&array);
	for (auto &a : array)
		a.showMsg();
	std::cout << std::endl;

	std::cout << "info._isZipped = true " << std::endl;
	info._isZipped = true;
	dataManager.Update(info);
	array.clear();
	dataManager.GetAllBackupAInfo(&array);
	for (auto &a : array)
		a.showMsg();
	std::cout << std::endl;

	std::cout << "GetOneByRealPath" << std::endl;
	dataManager.GetOneByRealPath(filename, &tmp);
	tmp.showMsg();
	std::cout << std::endl;
}
int main(int argc, char *argv[])
{
	// FileUtilTest(argv[1]);
	//  JsonUtilTest();
	//  ConfigTest();
	DataTest(argv[1]);

	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿猿收手吧!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值