这是我参与「第四届青训营 」笔记创作活动的第2天
编程思路:
用树形结构维护文件目录树,每个文件夹都看成是一个元数据节点,每个文件夹内的子文件则为其子节点,由于文件的路径是唯一的,则可以用map来建立一个路径到节点的映射。可以对其中的节点进行添加、删除、转移、重命名操作。
添加元数据节点:需要保证父目录存在,且合法(即只能添加在文件夹中),且该目录没有重名文件。新建一个节点作为父目录的子节点。
删除元数据节点:需要保证路径存在。并且删除该文件以及其所有子文件的元数据信息
重命名元数据节点:保证新旧路径都合法;然后将该节点与父节点断开,并加入新的父节点中去。
通过文件路径获取该文件的元数据:访问map,可以得到路径到节点的映射。
读写锁:由于客户端的读写操作是并发执行的,所以在同一时刻可能会进行多次读写。需要保证写操作的原子性,因此引入了读写锁。读操作与写操作互斥,可以同时存在多个读操作,但只能存在一个写操作,保证读写的一致性。(参考操作系统读者写者问题);优化方向:同一个区域同一个文件只能有一个进程进行读写操作,不同区域的文件可以同时进行读写。当对某个文件进行读写操作时,需要申请一个该位置的读写锁,即可增大并发度。
求所有文件的大小:初始文件为空,大小为0,当加入新文件时,设新文件的大小为size,其所有父目录的文件夹大小都增加size。删除文件则都减小size
\
struct FileTree
文件的元数据
struct FileTree{
string file_name;//文件名称
string file_path;//文件所在路径
long long size=0;//文件大小
int file_type; // 1: 文件夹; 0: 文件
unordered_map<int,int64_t> chunk_handles;
vector<int> next;//该文件夹的子文件映射
int x,y;
FileTree(){}
FileTree(string f_n,string f_p,long long _size,int f_t){
file_name=f_n;
file_path=f_p;
size =_size;
file_type=f_t;
}
};
文件夹的初始大小为0
GetFiles(string filePath)
Input: 根目录,初始目录为空
Output:建立一个空目录
int Print_Files(string path)
Input: 文件路径
Output:该路径下子文件的名称
\
vector Get_Metadata(string path)
Input: 文件路径
Output:该路径下子文件的元数据信息,用vector保存
\
bool Get_FileMetadata(string filepath,FileTree &node)
Input:filepath文件路径, node用于存储元数据信息
- Output: true:存在该路径,并且将元数据信息存储在node中;
- false:不存在该路径
\
int Add_Path(string filepath,FileTree node)
Input:输入添加的文件的路径,和该文件的元数据信息
- Output:0:该路径已存在同名文件,添加失败
- -1:路径不合法或不存在
- 1:添加成功
\
bool Del_Path(string filepath)
Input:输入需要删除的文件的路径
- Output:false:路径不存在
- true:删除成功
\
bool Rename_Path(string old_path,string filepath)
Input:old_path: 原文件路径
filepath: 新路径
Output:false:失败
true:成功
\
bool Exit_Path(string filepath)
判断路径是否存在
\
void Read_P(), Read_V()
读锁,可以多个用户同时读,与写操作互斥
\
Void Write_P(), Write_V()
写锁,同一时刻只能有一个用户写(可优化)
\
\