国税网站建设调查报告,百度搜索指数,做百度网站要注意什么,宁波网络公司设计装修1.需求 本题需要实现磁盘管理器DiskManager的相关接口#xff0c;磁盘管理器负责文件操作、读写页面等。阅读项目结构文档中磁盘管理器的相关说明#xff0c;以及代码框架中src/errors.h、src/storage/disk_manager.h、src/storage/disk_manager.cpp、src/common/config.h文件…1.需求 本题需要实现磁盘管理器DiskManager的相关接口磁盘管理器负责文件操作、读写页面等。阅读项目结构文档中磁盘管理器的相关说明以及代码框架中src/errors.h、src/storage/disk_manager.h、src/storage/disk_manager.cpp、src/common/config.h文件 实现以下接口 1void DiskManager::create_file(const std::string path); 该接口的参数path为文件名该接口的功能是创建文件其文件名为path参数指定的文件名。 2void DiskManager::open_file(const std::string path); 该接口的参数path为文件名该接口的功能是打开文件名参数path指定的文件。 3void DiskManager::close_file(const std::string path); 该接口的参数path为文件名该接口的功能是关闭文件名参数path指定的文件。 4void DiskManager::destroy_file(const std::string path); 该接口的参数path为文件名该接口的功能是删除文件名参数path指定的文件。 5void DiskManager::write_page(int fd, page_id_t page_no, const char *offset, int num_bytes); 该接口负责在文件的指定页面写入指定长度的数据该接口从指定页面的起始位置开始写入数据。 6void DiskManager::read_page(int fd, page_id_t page_no, char *offset, int num_bytes); 该接口需要从文件的指定页面读取指定长度的数据该接口从指定页面的起始位置开始读取数据。 2.熟悉框架
查看disk_manager数据结构path2fd_与fd2path_两张哈希表用来相互映射文件句柄和文件路径保证在O(1)的时间复杂度内查询两张表的功能为查看记录文件是否被打开存在于两张表的文件即为正在被打开的文件 private:// 文件打开列表用于记录文件是否被打开std::unordered_mapstd::string, int path2fd_; //Page文件磁盘路径,Page fd哈希表std::unordered_mapint, std::string fd2path_; //Page fd,Page文件磁盘路径哈希表int log_fd_ -1; // WAL日志文件的文件句柄默认为-1代表未打开日志文件std::atomicpage_id_t fd2pageno_[MAX_FD]{}; // 文件中已经分配的页面个数初始值为0
接着看另外一个重要的函数is_file
此函数的作用是通过文件路径判断该文件是否存在数据库中不在及时抛出异常防止异常访问导致段错误崩溃
/*** description: 判断指定路径文件是否存在* return {bool} 若指定路径文件存在则返回true * param {string} path 指定路径文件*/
bool DiskManager::is_file(const std::string path) {// 用struct stat获取文件信息struct stat st;return stat(path.c_str(), st) 0 S_ISREG(st.st_mode);
}所有的修改均在rucbase-lab/src/storage/disk_manager.cpp
3.实现功能
create_file(const std::string path) O_RDWR 是一个打开模式标志表示以可读写的方式打开文件。O_CREAT 是一个创建标志表示如果文件不存在则创建一个新文件。S_IRUSR | S_IWUSR 是权限标志表示用户具有读取和写入权限。 1.打开文件时既具有读写权限又能够创建文件 2.用户具有读取和写入权限 /*** description: 用于创建指定路径文件* return {*}* param {string} path*/
void DiskManager::create_file(const std::string path) {// Todo:// 调用open()函数使用O_CREAT模式// 注意不能重复创建相同文件if(is_file(path)) {throw FileExistsError(path);}//通过is_file函数保证不创建重复的文件int fd open(path.c_str(),O_RDWR | O_CREAT , S_IRUSR | S_IWUSR );if( fd 0) throw FileNotOpenError(fd);close(fd);
}destroy_file(const std::string path)
/*** description: 删除指定路径的文件* param {string} path 文件所在路径*/
void DiskManager::destroy_file(const std::string path) {// Todo:// 调用unlink()函数// 注意不能删除未关闭的文件if(!is_file(path)) throw FileNotFoundError(path);if(path2fd_.count(path)) throw FileNotClosedError(path);//文件未关闭unlink(path.c_str());
} open_file(const std::string path)
/*** description: 打开指定路径文件 * return {int} 返回打开的文件的文件句柄* param {string} path 文件所在路径*/
int DiskManager::open_file(const std::string path) {// Todo:// 调用open()函数使用O_RDWR模式// 注意不能重复打开相同文件并且需要更新文件打开列表if(!is_file(path)) throw FileNotFoundError(path);if(path2fd_.count(path)) throw FileNotClosedError(path);int fd open(path.c_str(),O_RDWR);//更新文件打开列表操作fd2path_[fd] path;path2fd_[path] fd;return fd;
}
close_file(int fd)
根据文件句柄查看文件是否未关闭关闭后即可清理哈希表中的映射
/*** description:用于关闭指定路径文件 * param {int} fd 打开的文件的文件句柄*/
void DiskManager::close_file(int fd) {// Todo:// 调用close()函数// 注意不能关闭未打开的文件并且需要更新文件打开列表if(!fd2path_.count(fd)){//该文件未打开throw FileNotOpenError(fd);}close(fd);path2fd_.erase(fd2path_[fd]);fd2path_.erase(fd);
}
DiskManager::write_page(int fd, page_id_t page_no, const char *offset, int num_bytes) fseek(FILE *stream, long offset, int whence); 1.offset表示文件指针的偏移量 SEEK_SET基准位置为文件开头即offset表示距离文件开头的偏移量。 SEEK_CUR基准位置为文件当前位置即offset表示距离文件当前位置的偏移量。 SEEK_END基准位置为文件末尾即offset表示距离文件末尾的偏移量。2.whence表示偏移量的基准位置 当whence为SEEK_SET时offset表示距离文件开头的偏移量 当whence为SEEK_CUR时offset表示距离文件当前位置的偏移量 当whence为SEEK_END时offset表示距离文件末尾的偏移量。 void DiskManager::write_page(int fd, page_id_t page_no, const char *offset, int num_bytes) {// Todo:// 1.lseek()定位到文件头通过(fd,page_no)可以定位指定页面及其在磁盘文件中的偏移量// 2.调用write()函数// 注意write返回值与num_bytes不等时 throw InternalError(DiskManager::write_page Error);lseek(fd,page_no*PAGE_SIZE,SEEK_SET);int write_bytes write(fd,offset,num_bytes);if(write_bytes0) throw InternalError(DiskManager::write_page Error);
}DiskManager::read_page(int fd, page_id_t page_no, char *offset, int num_bytes)
void DiskManager::read_page(int fd, page_id_t page_no, char *offset, int num_bytes) {// Todo:// 1.lseek()定位到文件头通过(fd,page_no)可以定位指定页面及其在磁盘文件中的偏移量// 2.调用read()函数// 注意read返回值与num_bytes不等时throw InternalError(DiskManager::read_page Error);lseek(fd,page_no*PAGE_SIZE,SEEK_SET);int read_bytes read(fd,offset,num_bytes);if(read_bytes0) throw InternalError(DiskManager::read_page Error);
}